History

feat: Add `gitoxide.core.defaultPackCacheMemoryLimit` to control memory limits. (#851)

Previously the 64 slot LRU cache didn't have any limit, now one is implemented that defaults to about 96MB.

Sebastian Thiel committed 3 years ago

Commit 020ff4e1 parent 969cc775 files · +33 −7Browse files

Unified · Split

5 files
  1. gix/src/config/cache/init.rs +7 −3
  2. gix/src/config/cache/util.rs +7 −2
  3. gix/src/config/mod.rs +2 −0
  4. gix/src/config/tree/sections/gitoxide.rs +11 −1
  5. gix/src/repository/init.rs +6 −1
gix/src/config/cache/init.rs+7−3
@@ -151,7 +151,7 @@ impl Cache { · 150 unmodified lines
151 lenient_config,151 lenient_config,
152 )?;152 )?;
153 let object_kind_hint = util::disambiguate_hint(&config, lenient_config)?;153 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) =
155 util::parse_object_caches(&config, lenient_config, filter_config_section)?;155 util::parse_object_caches(&config, lenient_config, filter_config_section)?;
156 // NOTE: When adding a new initial cache, consider adjusting `reread_values_and_clear_caches()` as well.156 // NOTE: When adding a new initial cache, consider adjusting `reread_values_and_clear_caches()` as well.
157 Ok(Cache {157 Ok(Cache {
@@ -159,6 +159,7 @@ impl Cache { · 1 unmodified line
159 use_multi_pack_index,159 use_multi_pack_index,
160 object_hash,160 object_hash,
161 object_kind_hint,161 object_kind_hint,
162 static_pack_cache_limit_bytes,
162 pack_cache_bytes,163 pack_cache_bytes,
163 object_cache_bytes,164 object_cache_bytes,
164 reflog,165 reflog,
@@ -222,8 +223,11 @@ impl Cache { · 57 unmodified lines
222 self.url_rewrite = Default::default();223 self.url_rewrite = Default::default();
223 self.diff_renames = Default::default();224 self.diff_renames = Default::default();
224 self.diff_algorithm = Default::default();225 self.diff_algorithm = Default::default();
225 (self.pack_cache_bytes, self.object_cache_bytes) =226 (
226 util::parse_object_caches(config, self.lenient_config, self.filter_config_section)?;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)?;
227 #[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))]231 #[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))]
228 {232 {
229 self.url_scheme = Default::default();233 self.url_scheme = Default::default();
gix/src/config/cache/util.rs+7−2
@@ -73,7 +73,12 @@ pub(crate) fn parse_object_caches( · 72 unmodified lines
73 config: &gix_config::File<'static>,73 config: &gix_config::File<'static>,
74 lenient: bool,74 lenient: bool,
75 mut filter_config_section: fn(&gix_config::file::Metadata) -> bool,75 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)?;
77 let pack_cache_bytes = config82 let pack_cache_bytes = config
78 .integer_filter_by_key("core.deltaBaseCacheLimit", &mut filter_config_section)83 .integer_filter_by_key("core.deltaBaseCacheLimit", &mut filter_config_section)
79 .map(|res| Core::DELTA_BASE_CACHE_LIMIT.try_into_usize(res))84 .map(|res| Core::DELTA_BASE_CACHE_LIMIT.try_into_usize(res))
@@ -85,7 +90,7 @@ pub(crate) fn parse_object_caches( · 5 unmodified lines
85 .transpose()90 .transpose()
86 .with_leniency(lenient)?91 .with_leniency(lenient)?
87 .unwrap_or_default();92 .unwrap_or_default();
88 Ok((pack_cache_bytes, object_cache_bytes))93 Ok((static_pack_cache_limit, pack_cache_bytes, object_cache_bytes))
89}94}
90 95
91pub(crate) fn parse_core_abbrev(96pub(crate) fn parse_core_abbrev(
gix/src/config/mod.rs+2−0
@@ -470,6 +470,8 @@ pub(crate) struct Cache { · 469 unmodified lines
470 pub(crate) pack_cache_bytes: Option<usize>,470 pub(crate) pack_cache_bytes: Option<usize>,
471 /// The amount of bytes to use for caching whole objects, or 0 to turn it off entirely.471 /// The amount of bytes to use for caching whole objects, or 0 to turn it off entirely.
472 pub(crate) object_cache_bytes: usize,472 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>,
473 /// The config section filter from the options used to initialize this instance. Keep these in sync!475 /// The config section filter from the options used to initialize this instance. Keep these in sync!
474 filter_config_section: fn(&gix_config::file::Metadata) -> bool,476 filter_config_section: fn(&gix_config::file::Metadata) -> bool,
475 /// The object kind to pick if a prefix is ambiguous.477 /// The object kind to pick if a prefix is ambiguous.
gix/src/config/tree/sections/gitoxide.rs+11−1
@@ -67,6 +67,11 @@ mod subsections { · 66 unmodified lines
67 pub struct Core;67 pub struct Core;
68 68
69 impl Core {69 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 );
70 /// The `gitoxide.core.useNsec` key.75 /// The `gitoxide.core.useNsec` key.
71 pub const USE_NSEC: keys::Boolean = keys::Boolean::new_boolean("useNsec", &Gitoxide::CORE)76 pub const USE_NSEC: keys::Boolean = keys::Boolean::new_boolean("useNsec", &Gitoxide::CORE)
72 .with_note("A runtime version of the USE_NSEC build flag.");77 .with_note("A runtime version of the USE_NSEC build flag.");
@@ -89,7 +94,12 @@ mod subsections { · 16 unmodified lines
89 }94 }
90 95
91 fn keys(&self) -> &[&dyn Key] {96 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 ]
93 }103 }
94 104
95 fn parent(&self) -> Option<&dyn Section> {105 fn parent(&self) -> Option<&dyn Section> {
gix/src/repository/init.rs+6−1
@@ -37,7 +37,12 @@ fn setup_objects(mut objects: crate::OdbHandle, config: &crate::config::Cache) - · 36 unmodified lines
37 #[cfg(feature = "max-performance-safe")]37 #[cfg(feature = "max-performance-safe")]
38 {38 {
39 match config.pack_cache_bytes {39 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 },
41 Some(0) => objects.unset_pack_cache(),46 Some(0) => objects.unset_pack_cache(),
42 Some(bytes) => objects.set_pack_cache(move || -> Box<gix_odb::cache::PackCache> {47 Some(bytes) => objects.set_pack_cache(move || -> Box<gix_odb::cache::PackCache> {
43 Box::new(gix_pack::cache::lru::MemoryCappedHashmap::new(bytes))48 Box::new(gix_pack::cache::lru::MemoryCappedHashmap::new(bytes))