Skip to content

Commit

Permalink
git: cache the extra metadata table
Browse files Browse the repository at this point in the history
Performance on repositories with many commits is limited somewhat by repeatedly
stating the tablestore directory to work out what the head is. By caching the
table rather than looking it up from disk on every request, we can much more
rapidly satisfy requests. 

This avoids the pathological case in #845 where jj operations take several
minutes to complete.

This patch doesn't change the normal flow of the write path: that will still
always call get_head() on the underlying TableStore, which will stat the
directory before writing out changes. It will however empty the cache when the
metadata has been written.

Fixes #845.
  • Loading branch information
lukegb committed Dec 11, 2022
1 parent 4a889b9 commit 4a39ca4
Showing 1 changed file with 16 additions and 5 deletions.
21 changes: 16 additions & 5 deletions lib/src/git_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::fmt::{Debug, Error, Formatter};
use std::fs::File;
use std::io::{Cursor, Read, Write};
use std::path::Path;
use std::sync::Mutex;
use std::sync::{Arc, Mutex};

use git2::Oid;
use itertools::Itertools;
Expand All @@ -29,7 +29,7 @@ use crate::backend::{
TreeId, TreeValue,
};
use crate::repo_path::{RepoPath, RepoPathComponent};
use crate::stacked_table::{TableSegment, TableStore};
use crate::stacked_table::{ReadonlyTable, TableSegment, TableStore};

const HASH_LENGTH: usize = 20;
/// Ref namespace used only for preventing GC.
Expand All @@ -50,6 +50,7 @@ pub struct GitBackend {
root_commit_id: CommitId,
empty_tree_id: TreeId,
extra_metadata_store: TableStore,
cached_extra_metadata: Mutex<Option<Arc<ReadonlyTable>>>,
}

impl GitBackend {
Expand All @@ -61,6 +62,7 @@ impl GitBackend {
root_commit_id,
empty_tree_id,
extra_metadata_store,
cached_extra_metadata: Mutex::new(None),
}
}

Expand Down Expand Up @@ -390,9 +392,17 @@ impl Backend for GitBackend {
committer,
};

let table = self.extra_metadata_store.get_head().map_err(|err| {
BackendError::Other(format!("Failed to read non-git metadata: {err}"))
})?;
let table = {
let mut locked_head = self.cached_extra_metadata.lock().unwrap();
match locked_head.take() {
Some(head) => Ok(head.clone()),
None => self.extra_metadata_store.get_head().map(|x| {
*locked_head = Some(x.clone());
x
}),
}
}
.map_err(|err| BackendError::Other(format!("Failed to read non-git metadata: {err}")))?;
let maybe_extras = table.get_value(git_commit_id.as_bytes());
if let Some(extras) = maybe_extras {
deserialize_extras(&mut commit, extras);
Expand Down Expand Up @@ -452,6 +462,7 @@ impl Backend for GitBackend {
.map_err(|err| {
BackendError::Other(format!("Failed to write non-git metadata: {err}"))
})?;
*self.cached_extra_metadata.lock().unwrap() = None;
Ok(id)
}
}
Expand Down

0 comments on commit 4a39ca4

Please sign in to comment.