Previously the 64 slot LRU cache didn't have any limit, now one is implemented that defaults to about 96MB.
Unified · Split
| @@ -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(); |
| @@ -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 = config | 82 | 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 | ||
| 91 | pub(crate) fn parse_core_abbrev( | 96 | pub(crate) fn parse_core_abbrev( |
| @@ -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. |
| @@ -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> { |
| @@ -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)) |