Skip to content

Commit

Permalink
Avoid infinite growth of the manifest cache during create_git_tree
Browse files Browse the repository at this point in the history
When starting off from changegroupv1, the manifest cache is not used at all
during the manifest import phase. With changegroupv2, this might happen with
a very linear history, too. In that case, in create_git_tree, we end up
filling the tree because we hit the case where we never had a hit and always
get misses (create_git_tree avoids requesting the same tree twice), and that
can use a ton of memory uselessly, storing hundreds of thousands of items.
Hopefully, this doesn't impact performance in the changegroupv2 case before
of the slow cache warmup this causes.

The ideal thing would be for the cache not to be used at all, but this is good
enough for now.
  • Loading branch information
glandium committed Nov 19, 2023
1 parent 08980f4 commit 23f77dc
Showing 1 changed file with 3 additions and 8 deletions.
11 changes: 3 additions & 8 deletions src/cinnabar/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::cell::RefCell;
use std::cmp;
use std::io::{self, Write};
use std::num::NonZeroUsize;

Expand Down Expand Up @@ -42,16 +41,14 @@ struct ManifestTreeCache {
lru_cache: LruCache<GitManifestTreeId, GitManifestTree>,
queries: usize,
misses: usize,
had_first_hit: bool,
}

impl ManifestTreeCache {
fn new() -> Self {
ManifestTreeCache {
lru_cache: LruCache::unbounded(),
lru_cache: LruCache::new(NonZeroUsize::new(100).unwrap()),
queries: 0,
misses: 0,
had_first_hit: false,
}
}

Expand All @@ -68,12 +65,10 @@ impl ManifestTreeCache {
f()
})
.map(Clone::clone);
self.had_first_hit |= self.misses != self.queries;
let queries_limit = cmp::max(100, self.lru_cache.len() / 2);
if self.queries >= queries_limit {
if self.queries >= self.lru_cache.cap().get() / 2 {
let miss_rate = self.misses / (self.queries / 10);
// Avoid growing the cache when we're flat-lining at 100% miss rate.
if !self.had_first_hit || (miss_rate >= 7 && self.misses != self.queries) {
if miss_rate >= 7 && self.misses != self.queries {
self.lru_cache.resize(
NonZeroUsize::new(self.lru_cache.len() + self.lru_cache.len() / 2 + 1).unwrap(),
);
Expand Down

0 comments on commit 23f77dc

Please sign in to comment.