forked from mirrors/jj
index: make IndexRef::entry_by_id() etc return entry with repo's lifetime
It's useful to be able to know that given a `repo: RepoRef<'a>`, the the lifetime of `repo.index().entry_by_id()` will also be `'a`.
This commit is contained in:
parent
209c62075e
commit
7861968f64
3 changed files with 55 additions and 39 deletions
|
@ -33,12 +33,12 @@ use crate::store::{ChangeId, CommitId};
|
|||
|
||||
#[derive(Clone)]
|
||||
pub enum IndexRef<'a> {
|
||||
Readonly(Arc<ReadonlyIndex>),
|
||||
Readonly(&'a ReadonlyIndex),
|
||||
Mutable(&'a MutableIndex),
|
||||
}
|
||||
|
||||
impl From<Arc<ReadonlyIndex>> for IndexRef<'_> {
|
||||
fn from(index: Arc<ReadonlyIndex>) -> Self {
|
||||
impl<'a> From<&'a ReadonlyIndex> for IndexRef<'a> {
|
||||
fn from(index: &'a ReadonlyIndex) -> Self {
|
||||
IndexRef::Readonly(index)
|
||||
}
|
||||
}
|
||||
|
@ -78,14 +78,14 @@ impl<'a> IndexRef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn entry_by_id(&self, commit_id: &CommitId) -> Option<IndexEntry> {
|
||||
pub fn entry_by_id(&self, commit_id: &CommitId) -> Option<IndexEntry<'a>> {
|
||||
match self {
|
||||
IndexRef::Readonly(index) => index.entry_by_id(commit_id),
|
||||
IndexRef::Mutable(index) => index.entry_by_id(commit_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn entry_by_pos(&self, pos: u32) -> IndexEntry {
|
||||
pub fn entry_by_pos(&self, pos: u32) -> IndexEntry<'a> {
|
||||
match self {
|
||||
IndexRef::Readonly(index) => index.entry_by_pos(pos),
|
||||
IndexRef::Mutable(index) => index.entry_by_pos(pos),
|
||||
|
@ -113,7 +113,7 @@ impl<'a> IndexRef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn walk_revs(&self, wanted: &[CommitId], unwanted: &[CommitId]) -> RevWalk {
|
||||
pub fn walk_revs(&self, wanted: &[CommitId], unwanted: &[CommitId]) -> RevWalk<'a> {
|
||||
match self {
|
||||
IndexRef::Readonly(index) => index.walk_revs(wanted, unwanted),
|
||||
IndexRef::Mutable(index) => index.walk_revs(wanted, unwanted),
|
||||
|
@ -772,7 +772,7 @@ impl<'a> CompositeIndex<'a> {
|
|||
self.0
|
||||
.segment_parent_file()
|
||||
.as_ref()
|
||||
.and_then(|file| IndexRef::Readonly(file.clone()).commit_id_to_pos(commit_id))
|
||||
.and_then(|file| IndexRef::Readonly(file).commit_id_to_pos(commit_id))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1564,8 +1564,10 @@ mod tests {
|
|||
fn index_empty(on_disk: bool) {
|
||||
let temp_dir = tempfile::tempdir().unwrap();
|
||||
let index = MutableIndex::full(3);
|
||||
let mut _saved_index = None;
|
||||
let index = if on_disk {
|
||||
IndexRef::Readonly(index.save_in(temp_dir.path().to_owned()).unwrap())
|
||||
_saved_index = Some(index.save_in(temp_dir.path().to_owned()).unwrap());
|
||||
IndexRef::Readonly(_saved_index.as_ref().unwrap())
|
||||
} else {
|
||||
IndexRef::Mutable(&index)
|
||||
};
|
||||
|
@ -1593,8 +1595,10 @@ mod tests {
|
|||
let id_0 = CommitId::from_hex("000000");
|
||||
let change_id0 = new_change_id();
|
||||
index.add_commit_data(id_0.clone(), change_id0.clone(), false, vec![], vec![]);
|
||||
let mut _saved_index = None;
|
||||
let index = if on_disk {
|
||||
IndexRef::Readonly(index.save_in(temp_dir.path().to_owned()).unwrap())
|
||||
_saved_index = Some(index.save_in(temp_dir.path().to_owned()).unwrap());
|
||||
IndexRef::Readonly(_saved_index.as_ref().unwrap())
|
||||
} else {
|
||||
IndexRef::Mutable(&index)
|
||||
};
|
||||
|
@ -1715,8 +1719,10 @@ mod tests {
|
|||
vec![id_4.clone(), id_2.clone()],
|
||||
vec![],
|
||||
);
|
||||
let mut _saved_index = None;
|
||||
let index = if on_disk {
|
||||
IndexRef::Readonly(index.save_in(temp_dir.path().to_owned()).unwrap())
|
||||
_saved_index = Some(index.save_in(temp_dir.path().to_owned()).unwrap());
|
||||
IndexRef::Readonly(_saved_index.as_ref().unwrap())
|
||||
} else {
|
||||
IndexRef::Mutable(&index)
|
||||
};
|
||||
|
@ -1839,8 +1845,10 @@ mod tests {
|
|||
vec![id_1, id_2, id_3, id_4, id_5],
|
||||
vec![],
|
||||
);
|
||||
let mut _saved_index = None;
|
||||
let index = if on_disk {
|
||||
IndexRef::Readonly(index.save_in(temp_dir.path().to_owned()).unwrap())
|
||||
_saved_index = Some(index.save_in(temp_dir.path().to_owned()).unwrap());
|
||||
IndexRef::Readonly(_saved_index.as_ref().unwrap())
|
||||
} else {
|
||||
IndexRef::Mutable(&index)
|
||||
};
|
||||
|
|
|
@ -84,7 +84,7 @@ impl<'a> RepoRef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn index(&self) -> IndexRef {
|
||||
pub fn index(&self) -> IndexRef<'a> {
|
||||
match self {
|
||||
RepoRef::Readonly(repo) => IndexRef::Readonly(repo.index()),
|
||||
RepoRef::Mutable(repo) => IndexRef::Mutable(repo.index()),
|
||||
|
@ -298,7 +298,7 @@ impl ReadonlyRepo {
|
|||
locked_evolution.as_ref().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn index(&self) -> Arc<ReadonlyIndex> {
|
||||
pub fn index(&self) -> &Arc<ReadonlyIndex> {
|
||||
let mut locked_index = self.index.lock().unwrap();
|
||||
if locked_index.is_none() {
|
||||
let op_id = self.op_id.clone();
|
||||
|
@ -306,10 +306,15 @@ impl ReadonlyRepo {
|
|||
let op = Operation::new(self.op_store.clone(), op_id, op);
|
||||
locked_index.replace(self.index_store.get_index_at_op(&op, self.store.as_ref()));
|
||||
}
|
||||
locked_index.as_ref().unwrap().clone()
|
||||
let index: &Arc<ReadonlyIndex> = locked_index.as_ref().unwrap();
|
||||
// Extend lifetime from that of mutex lock to that of self. Safe since we never
|
||||
// change value once it's been set (except in `reindex()` but that
|
||||
// requires a mutable reference).
|
||||
let index: &Arc<ReadonlyIndex> = unsafe { std::mem::transmute(index) };
|
||||
index
|
||||
}
|
||||
|
||||
pub fn reindex(&mut self) -> Arc<ReadonlyIndex> {
|
||||
pub fn reindex(&mut self) -> &Arc<ReadonlyIndex> {
|
||||
self.index_store.reinit();
|
||||
{
|
||||
let mut locked_index = self.index.lock().unwrap();
|
||||
|
@ -350,7 +355,7 @@ impl ReadonlyRepo {
|
|||
let locked_evolution = self.evolution.lock().unwrap();
|
||||
let mut_repo = MutableRepo::new(
|
||||
self.clone(),
|
||||
self.index(),
|
||||
self.index().clone(),
|
||||
&self.view,
|
||||
locked_evolution.as_ref(),
|
||||
);
|
||||
|
|
|
@ -50,11 +50,14 @@ fn test_index_commits_empty_repo(use_git: bool) {
|
|||
|
||||
// Check the generation numbers of the root and the working copy
|
||||
assert_eq!(
|
||||
generation_number(index.clone(), repo.store().root_commit_id()),
|
||||
generation_number(index.as_ref(), repo.store().root_commit_id()),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
generation_number(index, &repo.working_copy_locked().current_commit_id()),
|
||||
generation_number(
|
||||
index.as_ref(),
|
||||
&repo.working_copy_locked().current_commit_id()
|
||||
),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
@ -105,16 +108,16 @@ fn test_index_commits_standard_cases(use_git: bool) {
|
|||
assert_eq!(stats.num_merges, 1);
|
||||
assert_eq!(stats.max_generation_number, 6);
|
||||
|
||||
assert_eq!(generation_number(index.clone(), root_commit.id()), 0);
|
||||
assert_eq!(generation_number(index.clone(), wc_commit.id()), 1);
|
||||
assert_eq!(generation_number(index.clone(), commit_a.id()), 1);
|
||||
assert_eq!(generation_number(index.clone(), commit_b.id()), 2);
|
||||
assert_eq!(generation_number(index.clone(), commit_c.id()), 2);
|
||||
assert_eq!(generation_number(index.clone(), commit_d.id()), 3);
|
||||
assert_eq!(generation_number(index.clone(), commit_e.id()), 4);
|
||||
assert_eq!(generation_number(index.clone(), commit_f.id()), 5);
|
||||
assert_eq!(generation_number(index.clone(), commit_g.id()), 6);
|
||||
assert_eq!(generation_number(index.clone(), commit_h.id()), 5);
|
||||
assert_eq!(generation_number(index.as_ref(), root_commit.id()), 0);
|
||||
assert_eq!(generation_number(index.as_ref(), wc_commit.id()), 1);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_a.id()), 1);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_b.id()), 2);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_c.id()), 2);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_d.id()), 3);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_e.id()), 4);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_f.id()), 5);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_g.id()), 6);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_h.id()), 5);
|
||||
|
||||
assert!(index.is_ancestor(root_commit.id(), commit_a.id()));
|
||||
assert!(!index.is_ancestor(commit_a.id(), root_commit.id()));
|
||||
|
@ -181,11 +184,11 @@ fn test_index_commits_criss_cross(use_git: bool) {
|
|||
// Check generation numbers
|
||||
for gen in 0..num_generations {
|
||||
assert_eq!(
|
||||
generation_number(index.clone(), left_commits[gen].id()),
|
||||
generation_number(index.as_ref(), left_commits[gen].id()),
|
||||
(gen as u32) + 1
|
||||
);
|
||||
assert_eq!(
|
||||
generation_number(index.clone(), right_commits[gen].id()),
|
||||
generation_number(index.as_ref(), right_commits[gen].id()),
|
||||
(gen as u32) + 1
|
||||
);
|
||||
}
|
||||
|
@ -291,9 +294,9 @@ fn test_index_commits_previous_operations(use_git: bool) {
|
|||
assert_eq!(stats.num_merges, 0);
|
||||
assert_eq!(stats.max_generation_number, 3);
|
||||
|
||||
assert_eq!(generation_number(index.clone(), commit_a.id()), 1);
|
||||
assert_eq!(generation_number(index.clone(), commit_b.id()), 2);
|
||||
assert_eq!(generation_number(index, commit_c.id()), 3);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_a.id()), 1);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_b.id()), 2);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_c.id()), 3);
|
||||
}
|
||||
|
||||
#[test_case(false ; "local store")]
|
||||
|
@ -339,10 +342,10 @@ fn test_index_commits_incremental(use_git: bool) {
|
|||
assert_eq!(stats.levels.len(), 1);
|
||||
assert_eq!(stats.levels[0].num_commits, 5);
|
||||
|
||||
assert_eq!(generation_number(index.clone(), root_commit.id()), 0);
|
||||
assert_eq!(generation_number(index.clone(), commit_a.id()), 1);
|
||||
assert_eq!(generation_number(index.clone(), commit_b.id()), 2);
|
||||
assert_eq!(generation_number(index, commit_c.id()), 3);
|
||||
assert_eq!(generation_number(index.as_ref(), root_commit.id()), 0);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_a.id()), 1);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_b.id()), 2);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_c.id()), 3);
|
||||
}
|
||||
|
||||
#[test_case(false ; "local store")]
|
||||
|
@ -385,8 +388,8 @@ fn test_index_commits_incremental_empty_transaction(use_git: bool) {
|
|||
assert_eq!(stats.levels[1].num_commits, 1);
|
||||
assert_ne!(stats.levels[1].name, stats.levels[0].name);
|
||||
|
||||
assert_eq!(generation_number(index.clone(), root_commit.id()), 0);
|
||||
assert_eq!(generation_number(index, commit_a.id()), 1);
|
||||
assert_eq!(generation_number(index.as_ref(), root_commit.id()), 0);
|
||||
assert_eq!(generation_number(index.as_ref(), commit_a.id()), 1);
|
||||
}
|
||||
|
||||
#[test_case(false ; "local store")]
|
||||
|
|
Loading…
Reference in a new issue