Skip to content

Commit dad4851

Browse files
committed
feat: Add gitoxide.core.defaultPackCacheMemoryLimit to control memory limits.
Previously the 64 slot LRU cache didn't have any limit, now one is implemented that defaults to about 96MB.
1 parent cb22698 commit dad4851

File tree

5 files changed

+33
-7
lines changed

5 files changed

+33
-7
lines changed

gix/src/config/cache/init.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,15 @@ impl Cache {
151151
lenient_config,
152152
)?;
153153
let object_kind_hint = util::disambiguate_hint(&config, lenient_config)?;
154-
let (pack_cache_bytes, object_cache_bytes) =
154+
let (static_pack_cache_limit_bytes, pack_cache_bytes, object_cache_bytes) =
155155
util::parse_object_caches(&config, lenient_config, filter_config_section)?;
156156
// NOTE: When adding a new initial cache, consider adjusting `reread_values_and_clear_caches()` as well.
157157
Ok(Cache {
158158
resolved: config.into(),
159159
use_multi_pack_index,
160160
object_hash,
161161
object_kind_hint,
162+
static_pack_cache_limit_bytes,
162163
pack_cache_bytes,
163164
object_cache_bytes,
164165
reflog,
@@ -222,8 +223,11 @@ impl Cache {
222223
self.url_rewrite = Default::default();
223224
self.diff_renames = Default::default();
224225
self.diff_algorithm = Default::default();
225-
(self.pack_cache_bytes, self.object_cache_bytes) =
226-
util::parse_object_caches(config, self.lenient_config, self.filter_config_section)?;
226+
(
227+
self.static_pack_cache_limit_bytes,
228+
self.pack_cache_bytes,
229+
self.object_cache_bytes,
230+
) = util::parse_object_caches(config, self.lenient_config, self.filter_config_section)?;
227231
#[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))]
228232
{
229233
self.url_scheme = Default::default();

gix/src/config/cache/util.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,12 @@ pub(crate) fn parse_object_caches(
7373
config: &gix_config::File<'static>,
7474
lenient: bool,
7575
mut filter_config_section: fn(&gix_config::file::Metadata) -> bool,
76-
) -> Result<(Option<usize>, usize), Error> {
76+
) -> Result<(Option<usize>, Option<usize>, usize), Error> {
77+
let static_pack_cache_limit = config
78+
.integer_filter_by_key("core.deltaBaseCacheLimit", &mut filter_config_section)
79+
.map(|res| gitoxide::Core::DEFAULT_PACK_CACHE_MEMORY_LIMIT.try_into_usize(res))
80+
.transpose()
81+
.with_leniency(lenient)?;
7782
let pack_cache_bytes = config
7883
.integer_filter_by_key("core.deltaBaseCacheLimit", &mut filter_config_section)
7984
.map(|res| Core::DELTA_BASE_CACHE_LIMIT.try_into_usize(res))
@@ -85,7 +90,7 @@ pub(crate) fn parse_object_caches(
8590
.transpose()
8691
.with_leniency(lenient)?
8792
.unwrap_or_default();
88-
Ok((pack_cache_bytes, object_cache_bytes))
93+
Ok((static_pack_cache_limit, pack_cache_bytes, object_cache_bytes))
8994
}
9095

9196
pub(crate) fn parse_core_abbrev(

gix/src/config/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,8 @@ pub(crate) struct Cache {
470470
pub(crate) pack_cache_bytes: Option<usize>,
471471
/// The amount of bytes to use for caching whole objects, or 0 to turn it off entirely.
472472
pub(crate) object_cache_bytes: usize,
473+
/// The amount of bytes we can hold in our static LRU cache. Otherwise, go with the defaults.
474+
pub(crate) static_pack_cache_limit_bytes: Option<usize>,
473475
/// The config section filter from the options used to initialize this instance. Keep these in sync!
474476
filter_config_section: fn(&gix_config::file::Metadata) -> bool,
475477
/// The object kind to pick if a prefix is ambiguous.

gix/src/config/tree/sections/gitoxide.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ mod subsections {
6767
pub struct Core;
6868

6969
impl Core {
70+
/// The `gitoxide.core.defaultPackCacheMemoryLimit` key.
71+
pub const DEFAULT_PACK_CACHE_MEMORY_LIMIT: keys::UnsignedInteger =
72+
keys::UnsignedInteger::new_unsigned_integer("defaultPackCacheMemoryLimit", &Gitoxide::CORE).with_note(
73+
"If unset, we default to 96MB memory cap for the default 64 slot LRU cache for object deltas.",
74+
);
7075
/// The `gitoxide.core.useNsec` key.
7176
pub const USE_NSEC: keys::Boolean = keys::Boolean::new_boolean("useNsec", &Gitoxide::CORE)
7277
.with_note("A runtime version of the USE_NSEC build flag.");
@@ -89,7 +94,12 @@ mod subsections {
8994
}
9095

9196
fn keys(&self) -> &[&dyn Key] {
92-
&[&Self::USE_NSEC, &Self::USE_STDEV, &Self::SHALLOW_FILE]
97+
&[
98+
&Self::DEFAULT_PACK_CACHE_MEMORY_LIMIT,
99+
&Self::USE_NSEC,
100+
&Self::USE_STDEV,
101+
&Self::SHALLOW_FILE,
102+
]
93103
}
94104

95105
fn parent(&self) -> Option<&dyn Section> {

gix/src/repository/init.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,12 @@ fn setup_objects(mut objects: crate::OdbHandle, config: &crate::config::Cache) -
3737
#[cfg(feature = "max-performance-safe")]
3838
{
3939
match config.pack_cache_bytes {
40-
None => objects.set_pack_cache(|| Box::<gix_pack::cache::lru::StaticLinkedList<64>>::default()),
40+
None => match config.static_pack_cache_limit_bytes {
41+
None => objects.set_pack_cache(|| Box::<gix_pack::cache::lru::StaticLinkedList<64>>::default()),
42+
Some(limit) => {
43+
objects.set_pack_cache(move || Box::new(gix_pack::cache::lru::StaticLinkedList::<64>::new(limit)))
44+
}
45+
},
4146
Some(0) => objects.unset_pack_cache(),
4247
Some(bytes) => objects.set_pack_cache(move || -> Box<gix_odb::cache::PackCache> {
4348
Box::new(gix_pack::cache::lru::MemoryCappedHashmap::new(bytes))

0 commit comments

Comments
 (0)