author | Georges Racinet <georges.racinet@cloudcrane.io> |
Sun, 22 Dec 2024 17:02:09 +0100 | |
changeset 52792 | acae91fad6be |
parent 52780 | 42b219a1404a |
permissions | -rw-r--r-- |
52776
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
1 |
// store.rs |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
2 |
// |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
3 |
// Copyright 2020-2024 Raphaël Gomès <raphael.gomes@octobus.net> |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
4 |
// 2024 Georges Racinet <georges.racinet@cloudcrane.io> |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
5 |
// |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
6 |
// This software may be used and distributed according to the terms of the |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
7 |
// GNU General Public License version 2 or any later version. |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
8 |
use pyo3::prelude::*; |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
9 |
use pyo3::types::PyBytes; |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
10 |
|
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
11 |
use std::sync::atomic::{AtomicBool, Ordering}; |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
12 |
|
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
13 |
use hg::{fncache::FnCache, utils::files::get_bytes_from_path}; |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
14 |
|
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
15 |
pub struct PyFnCache { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
16 |
fncache: PyObject, |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
17 |
} |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
18 |
|
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
19 |
impl PyFnCache { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
20 |
pub fn new(fncache: PyObject) -> Self { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
21 |
Self { fncache } |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
22 |
} |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
23 |
} |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
24 |
|
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
25 |
impl Clone for PyFnCache { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
26 |
fn clone(&self) -> Self { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
27 |
Python::with_gil(|py| Self { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
28 |
fncache: self.fncache.clone_ref(py), |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
29 |
}) |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
30 |
} |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
31 |
} |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
32 |
|
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
33 |
/// Cache whether the fncache is loaded to avoid Python round-trip every time. |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
34 |
/// Once the fncache is loaded, it stays loaded unless we're in a very |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
35 |
/// long-running process, none of which we actually support for now. |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
36 |
static FN_CACHE_IS_LOADED: AtomicBool = AtomicBool::new(false); |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
37 |
|
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
38 |
// TODO perhaps a bit of magic with `Bound<'_, PyFnCache>` would spare us |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
39 |
// the GIL reacquisitions |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
40 |
impl FnCache for PyFnCache { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
41 |
fn is_loaded(&self) -> bool { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
42 |
if FN_CACHE_IS_LOADED.load(Ordering::Relaxed) { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
43 |
return true; |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
44 |
} |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
45 |
Python::with_gil(|py| { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
46 |
// TODO raise in case of error? |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
47 |
let is_loaded = self |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
48 |
.fncache |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
49 |
.getattr(py, "is_loaded") |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
50 |
.ok() |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
51 |
.map(|o| { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
52 |
o.extract::<bool>(py).expect( |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
53 |
"is_loaded returned something other than a bool", |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
54 |
) |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
55 |
}) |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
56 |
.unwrap_or(false); |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
57 |
if is_loaded { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
58 |
FN_CACHE_IS_LOADED.store(true, Ordering::Relaxed); |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
59 |
} |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
60 |
is_loaded |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
61 |
}) |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
62 |
} |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
63 |
fn add(&self, path: &std::path::Path) { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
64 |
Python::with_gil(|py| { |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
65 |
// TODO raise in case of error? |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
66 |
self.fncache |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
67 |
.call_method( |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
68 |
py, |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
69 |
"add", |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
70 |
(PyBytes::new(py, &get_bytes_from_path(path)),), |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
71 |
None, |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
72 |
) |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
73 |
.ok(); |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
74 |
}) |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
75 |
} |
6fa23eed335b
rust-pyo3: PyFnCache
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
76 |
} |