rust/hg-pyo3/src/revlog/config.rs
author Pierre-Yves David <pierre-yves.david@octobus.net>
Tue, 18 Feb 2025 22:24:08 +0100
changeset 52964 469b9a628b51
parent 52780 42b219a1404a
permissions -rw-r--r--
dirstatemap: update, document and type the identity tracking This new form should hopefully be clearer and less error prone.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52778
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     1
// revlog/config.rs
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     2
//
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     3
// Copyright 2020-2024 Raphaël Gomès <raphael.gomes@octobus.net>
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     4
//           2024 Georges Racinet <georges.racinet@cloudcrane.io>
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     5
//
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     6
// This software may be used and distributed according to the terms of the
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     7
// GNU General Public License version 2 or any later version.
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     8
use pyo3::conversion::FromPyObject;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     9
use pyo3::exceptions::PyValueError;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    10
use pyo3::intern;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    11
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    12
use pyo3::prelude::*;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    13
use pyo3::types::{PyBytes, PyDict, PyDictMethods};
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    14
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    15
use std::sync::OnceLock;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    16
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    17
use hg::revlog::{
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    18
    compression::CompressionConfig,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    19
    options::{RevlogDataConfig, RevlogDeltaConfig, RevlogFeatureConfig},
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    20
    RevlogType,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    21
};
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    22
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    23
/// Helper trait for configuration dicts
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    24
///
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    25
/// In Mercurial, it is customary for such dicts to have bytes keys.
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    26
trait ConfigPyDict<'a, 'py: 'a, D: FromPyObject<'py>> {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    27
    fn extract_item(&'a self, key: &[u8]) -> PyResult<Option<D>>;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    28
}
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    29
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    30
impl<'a, 'py, D> ConfigPyDict<'a, 'py, D> for Bound<'py, PyDict>
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    31
where
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    32
    'py: 'a,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    33
    D: FromPyObject<'py>,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    34
{
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    35
    fn extract_item(&'a self, key: &[u8]) -> PyResult<Option<D>> {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    36
        let py_item = self.get_item(PyBytes::new(self.py(), key))?;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    37
        match py_item {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    38
            Some(value) => {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    39
                if value.is_none() {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    40
                    Ok(None)
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    41
                } else {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    42
                    Ok(Some(value.extract()?))
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    43
                }
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    44
            }
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    45
            None => Ok(None),
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    46
        }
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    47
    }
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    48
}
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    49
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    50
/// Extraction helper for PyObject attributes.
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    51
///
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    52
/// `$obj` is a `Bound('_, PyAny)` and `$attr` is a static String slice.
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    53
/// This is both syntactic sugar and more efficient than using `getattr()`
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    54
/// manually, as this uses [`intern!`] for efficiency.
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    55
///
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    56
/// See the many examples in this module.
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    57
///
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    58
/// This does not work to return references (e.g. bytes). Quoting the
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    59
/// compiler: "returns a value referencing data owned by the current function"
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    60
macro_rules! extract_attr {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    61
    ($obj: expr, $attr: expr) => {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    62
        $obj.getattr(intern!($obj.py(), $attr))
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    63
            .and_then(|a| a.extract())
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    64
    };
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    65
}
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    66
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    67
// There are no static generics in Rust (because their implementation is
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    68
// hard, I'm guessing it's due to different compilation stages, etc.).
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    69
// So manually generate all three caches and use them in
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    70
// `with_filelog_cache`.
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    71
static DELTA_CONFIG_CACHE: OnceLock<(PyObject, RevlogDeltaConfig)> =
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    72
    OnceLock::new();
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    73
static DATA_CONFIG_CACHE: OnceLock<(PyObject, RevlogDataConfig)> =
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    74
    OnceLock::new();
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    75
static FEATURE_CONFIG_CACHE: OnceLock<(PyObject, RevlogFeatureConfig)> =
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    76
    OnceLock::new();
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    77
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    78
/// TODO don't do this and build a `Config` in Rust, expose it to Python and
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    79
/// downcast it (after refactoring Python to re-use the same config objects?).
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    80
///
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    81
/// Cache the first conversion from Python of filelog config. Other
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    82
/// revlog types are not cached.
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    83
///
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    84
/// All filelogs in a given repository *most likely* have the
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    85
/// exact same config, hence it makes a difference to look it up
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    86
/// from Python code only once, especially given that it can be in a
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    87
/// loop.
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    88
fn with_filelog_config_cache<T: Copy>(
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    89
    py_config: &Bound<'_, PyAny>,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    90
    revlog_type: RevlogType,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    91
    cache: &OnceLock<(PyObject, T)>,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    92
    callback: impl Fn() -> PyResult<T>,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    93
) -> PyResult<T> {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    94
    let mut was_cached = false;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    95
    if revlog_type == RevlogType::Filelog {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    96
        if let Some((cached_py_config, rust_config)) = cache.get() {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    97
            was_cached = true;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    98
            // it's not impossible that some extensions
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    99
            // do some magic with configs or that this code will be used
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   100
            // for longer-running processes. So compare the source
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   101
            // `PyObject` in case the source changed, at
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   102
            // the cost of some overhead. We can't use
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   103
            // `py_config.eq(cached_py_config)` because all config
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   104
            // objects are different in Python and `a is b` is false.
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   105
            if py_config.compare(cached_py_config)?.is_eq() {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   106
                return Ok(*rust_config);
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   107
            }
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   108
        }
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   109
    }
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   110
    let config = callback()?;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   111
    // Do not call the lock unnecessarily if it's already been set.
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   112
    if !was_cached && revlog_type == RevlogType::Filelog {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   113
        cache.set((py_config.clone().unbind(), config)).ok();
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   114
    }
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   115
    Ok(config)
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   116
}
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   117
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   118
pub fn extract_delta_config(
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   119
    conf: &Bound<'_, PyAny>,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   120
    revlog_type: RevlogType,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   121
) -> PyResult<RevlogDeltaConfig> {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   122
    with_filelog_config_cache(conf, revlog_type, &DELTA_CONFIG_CACHE, || {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   123
        let max_deltachain_span: i64 =
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   124
            extract_attr!(conf, "max_deltachain_span")?;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   125
        let revlog_delta_config = RevlogDeltaConfig {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   126
            general_delta: extract_attr!(conf, "general_delta")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   127
            sparse_revlog: extract_attr!(conf, "sparse_revlog")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   128
            max_chain_len: extract_attr!(conf, "max_chain_len")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   129
            max_deltachain_span: if max_deltachain_span < 0 {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   130
                None
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   131
            } else {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   132
                Some(max_deltachain_span as u64)
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   133
            },
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   134
            upper_bound_comp: extract_attr!(conf, "upper_bound_comp")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   135
            delta_both_parents: extract_attr!(conf, "delta_both_parents")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   136
            candidate_group_chunk_size: extract_attr!(
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   137
                conf,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   138
                "candidate_group_chunk_size"
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   139
            )?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   140
            debug_delta: extract_attr!(conf, "debug_delta")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   141
            lazy_delta: extract_attr!(conf, "lazy_delta")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   142
            lazy_delta_base: extract_attr!(conf, "lazy_delta_base")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   143
        };
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   144
        Ok(revlog_delta_config)
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   145
    })
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   146
}
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   147
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   148
pub fn extract_data_config(
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   149
    conf: &Bound<'_, PyAny>,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   150
    revlog_type: RevlogType,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   151
) -> PyResult<RevlogDataConfig> {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   152
    with_filelog_config_cache(conf, revlog_type, &DATA_CONFIG_CACHE, || {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   153
        Ok(RevlogDataConfig {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   154
            try_pending: extract_attr!(conf, "try_pending")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   155
            try_split: extract_attr!(conf, "try_split")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   156
            check_ambig: extract_attr!(conf, "check_ambig")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   157
            mmap_large_index: extract_attr!(conf, "mmap_large_index")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   158
            mmap_index_threshold: extract_attr!(conf, "mmap_index_threshold")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   159
            chunk_cache_size: extract_attr!(conf, "chunk_cache_size")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   160
            uncompressed_cache_factor: extract_attr!(
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   161
                conf,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   162
                "uncompressed_cache_factor"
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   163
            )?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   164
            uncompressed_cache_count: extract_attr!(
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   165
                conf,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   166
                "uncompressed_cache_count"
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   167
            )?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   168
            with_sparse_read: extract_attr!(conf, "with_sparse_read")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   169
            sr_density_threshold: extract_attr!(conf, "sr_density_threshold")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   170
            sr_min_gap_size: extract_attr!(conf, "sr_min_gap_size")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   171
            general_delta: extract_attr!(conf, "generaldelta")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   172
        })
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   173
    })
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   174
}
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   175
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   176
fn extract_compression_config(
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   177
    conf: &Bound<'_, PyAny>,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   178
) -> PyResult<CompressionConfig> {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   179
    let compression_options: Bound<'_, PyDict> =
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   180
        extract_attr!(conf, "compression_engine_options")?;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   181
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   182
    let name_bound = conf.getattr("compression_engine")?;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   183
    let name_bytes: &[u8] = name_bound.extract()?;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   184
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   185
    let compression_engine = match name_bytes {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   186
        b"zlib" => {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   187
            let level = compression_options.extract_item(b"zlib.level")?;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   188
            let mut engine = CompressionConfig::default();
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   189
            if let Some(level) = level {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   190
                engine
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   191
                    .set_level(level)
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   192
                    .expect("invalid compression level from Python");
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   193
            }
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   194
            engine
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   195
        }
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   196
        b"zstd" => {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   197
            let zstd_level =
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   198
                compression_options.extract_item(b"zstd.level")?;
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   199
            let level = if let Some(level) = zstd_level {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   200
                Some(level)
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   201
            } else {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   202
                compression_options.extract_item(b"level")?
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   203
            };
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   204
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   205
            CompressionConfig::zstd(level)
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   206
                .expect("invalid compression level from Python")
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   207
        }
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   208
        b"none" => CompressionConfig::None,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   209
        unknown => {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   210
            return Err(PyValueError::new_err(format!(
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   211
                "invalid compression engine {}",
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   212
                String::from_utf8_lossy(unknown)
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   213
            )));
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   214
        }
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   215
    };
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   216
    Ok(compression_engine)
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   217
}
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   218
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   219
pub fn extract_feature_config(
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   220
    conf: &Bound<'_, PyAny>,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   221
    revlog_type: RevlogType,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   222
) -> PyResult<RevlogFeatureConfig> {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   223
    with_filelog_config_cache(conf, revlog_type, &FEATURE_CONFIG_CACHE, || {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   224
        Ok(RevlogFeatureConfig {
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   225
            compression_engine: extract_compression_config(conf)?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   226
            censorable: extract_attr!(conf, "censorable")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   227
            has_side_data: extract_attr!(conf, "has_side_data")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   228
            compute_rank: extract_attr!(conf, "compute_rank")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   229
            canonical_parent_order: extract_attr!(
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   230
                conf,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   231
                "canonical_parent_order"
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   232
            )?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   233
            enable_ellipsis: extract_attr!(conf, "enable_ellipsis")?,
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   234
        })
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   235
    })
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   236
}