From 4c982fb14c7b37faba2b8f3b13c48b5acd85a560 Mon Sep 17 00:00:00 2001 From: Ronan Pelliard Date: Mon, 6 Oct 2025 07:12:04 +0200 Subject: [PATCH 1/2] Add bindings for cache size options --- src/opts.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/opts.rs b/src/opts.rs index af5bb0cf9f..d0364399dd 100644 --- a/src/opts.rs +++ b/src/opts.rs @@ -111,6 +111,41 @@ pub unsafe fn set_cache_object_limit(kind: ObjectType, size: libc::size_t) -> Re Ok(()) } +/// Set the maximum total data size that will be cached in memory across all +/// repositories before libgit2 starts evicting objects from the cache. This +/// is a soft limit, in that the library might briefly exceed it, but will start +/// aggressively evicting objects from cache when that happens. The default +/// cache size is 256MB. +/// +/// # Safety +/// This function is modifying a C global without synchronization, so it is not +/// thread safe, and should only be called before any thread is spawned. +pub unsafe fn set_cache_max_size(size: libc::size_t) -> Result<(), Error> { + crate::init(); + try_call!(raw::git_libgit2_opts( + raw::GIT_OPT_SET_CACHE_MAX_SIZE as libc::c_int, + size + )); + Ok(()) +} + +/// Get the current bytes in cache and the maximum that would be allowed in the cache. +/// +/// # Safety +/// This function is reading a C global without synchronization, so it is not +/// thread safe, and should only be called before any thread is spawned. +pub unsafe fn get_cached_memory() -> Result<(libc::size_t, libc::size_t), Error> { + crate::init(); + let mut current = 0; + let mut allowed = 0; + try_call!(raw::git_libgit2_opts( + raw::GIT_OPT_GET_CACHED_MEMORY as libc::c_int, + &mut current, + &mut allowed + )); + Ok((current, allowed)) +} + /// Controls whether or not libgit2 will verify when writing an object that all /// objects it references are valid. Enabled by default, but disabling this can /// significantly improve performance, at the cost of potentially allowing the From 87ec58bdef633378e75e99d4037a1eaf1f0d40bf Mon Sep 17 00:00:00 2001 From: Ronan Pelliard Date: Mon, 6 Oct 2025 20:16:54 +0200 Subject: [PATCH 2/2] use signed type and add tests --- src/opts.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/opts.rs b/src/opts.rs index d0364399dd..232d81e996 100644 --- a/src/opts.rs +++ b/src/opts.rs @@ -120,7 +120,7 @@ pub unsafe fn set_cache_object_limit(kind: ObjectType, size: libc::size_t) -> Re /// # Safety /// This function is modifying a C global without synchronization, so it is not /// thread safe, and should only be called before any thread is spawned. -pub unsafe fn set_cache_max_size(size: libc::size_t) -> Result<(), Error> { +pub unsafe fn set_cache_max_size(size: libc::ssize_t) -> Result<(), Error> { crate::init(); try_call!(raw::git_libgit2_opts( raw::GIT_OPT_SET_CACHE_MAX_SIZE as libc::c_int, @@ -134,7 +134,7 @@ pub unsafe fn set_cache_max_size(size: libc::size_t) -> Result<(), Error> { /// # Safety /// This function is reading a C global without synchronization, so it is not /// thread safe, and should only be called before any thread is spawned. -pub unsafe fn get_cached_memory() -> Result<(libc::size_t, libc::size_t), Error> { +pub unsafe fn get_cached_memory() -> Result<(libc::ssize_t, libc::ssize_t), Error> { crate::init(); let mut current = 0; let mut allowed = 0; @@ -519,4 +519,12 @@ mod test { assert!(get_server_timeout_in_milliseconds().unwrap() == 10_000); } } + + #[test] + fn cache_size() { + unsafe { + assert!(set_cache_max_size(20 * 1024 * 1024).is_ok()); + assert!(get_cached_memory().is_ok_and(|m| m.1 == 20 * 1024 * 1024)); + } + } }