Use cached canonical `rad/id` refs
We were recomputing the `rad/id` ref every time it was accessed.
This commit is contained in:
parent
87f47cdc67
commit
b20f81eb0c
|
|
@ -230,9 +230,12 @@ impl Proposal {
|
|||
self.description().unwrap_or_default()
|
||||
);
|
||||
let current = doc.update(remote, &msg, &signatures.collect::<Vec<_>>(), repo.raw())?;
|
||||
let head = repo.set_identity_head()?;
|
||||
|
||||
assert_eq!(head, current);
|
||||
|
||||
Ok(Identity {
|
||||
head: current,
|
||||
head,
|
||||
root: previous.root,
|
||||
current,
|
||||
revision: previous.revision + 1,
|
||||
|
|
|
|||
|
|
@ -165,7 +165,6 @@ pub fn fork<G: Signer, S: storage::WriteStorage>(
|
|||
) -> Result<(), ForkError> {
|
||||
let me = signer.public_key();
|
||||
let repository = storage.repository_mut(rid)?;
|
||||
// TODO: We should get the id branch pointer from a stored canonical reference.
|
||||
let (canonical_id, _) = repository.identity_doc()?;
|
||||
let (canonical_branch, canonical_head) = repository.head()?;
|
||||
let raw = repository.raw();
|
||||
|
|
|
|||
|
|
@ -310,64 +310,6 @@ impl Repository {
|
|||
Ok(verified)
|
||||
}
|
||||
|
||||
/// Return the canonical identity [`git::Oid`] and document.
|
||||
pub fn identity_doc(&self) -> Result<(Oid, identity::Doc<Unverified>), IdentityError> {
|
||||
let head = self.identity_head()?;
|
||||
|
||||
Doc::<Unverified>::load_at(head, self)
|
||||
.map(|(doc, _)| (head, doc))
|
||||
.map_err(IdentityError::from)
|
||||
}
|
||||
|
||||
/// Return the canonical identity branch head.
|
||||
pub fn identity_head(&self) -> Result<Oid, IdentityError> {
|
||||
let mut heads = Vec::new();
|
||||
|
||||
for remote in self.remote_ids()? {
|
||||
let remote = remote?;
|
||||
let oid = Doc::<Unverified>::head(&remote, self)?;
|
||||
|
||||
heads.push(oid.into());
|
||||
}
|
||||
// Keep track of the longest identity branch.
|
||||
let mut longest = heads.pop().ok_or(IdentityError::MissingBranch)?;
|
||||
|
||||
for head in &heads {
|
||||
let base = self.raw().merge_base(*head, longest)?;
|
||||
|
||||
if base == longest {
|
||||
// `head` is a successor of `longest`. Update `longest`.
|
||||
//
|
||||
// o head
|
||||
// |
|
||||
// o longest (base)
|
||||
// |
|
||||
//
|
||||
longest = *head;
|
||||
} else if base == *head || *head == longest {
|
||||
// `head` is an ancestor of `longest`, or equal to it. Do nothing.
|
||||
//
|
||||
// o longest o longest, head (base)
|
||||
// | |
|
||||
// o head (base) OR o
|
||||
// | |
|
||||
//
|
||||
} else {
|
||||
// The merge base between `head` and `longest` (`base`)
|
||||
// is neither `head` nor `longest`. Therefore, the branches have
|
||||
// diverged.
|
||||
//
|
||||
// longest head
|
||||
// \ /
|
||||
// o (base)
|
||||
// |
|
||||
//
|
||||
return Err(IdentityError::BranchesDiverge);
|
||||
}
|
||||
}
|
||||
Ok(longest.into())
|
||||
}
|
||||
|
||||
pub fn remote_ids(
|
||||
&self,
|
||||
) -> Result<impl Iterator<Item = Result<RemoteId, refs::Error>> + '_, git2::Error> {
|
||||
|
|
@ -554,7 +496,11 @@ impl ReadRepository for Repository {
|
|||
}
|
||||
|
||||
fn identity_doc(&self) -> Result<(Oid, identity::Doc<Unverified>), IdentityError> {
|
||||
Repository::identity_doc(self)
|
||||
let head = self.identity_head()?;
|
||||
|
||||
Doc::<Unverified>::load_at(head, self)
|
||||
.map(|(doc, _)| (head, doc))
|
||||
.map_err(IdentityError::from)
|
||||
}
|
||||
|
||||
fn head(&self) -> Result<(Qualified, Oid), IdentityError> {
|
||||
|
|
@ -568,8 +514,6 @@ impl ReadRepository for Repository {
|
|||
}
|
||||
|
||||
fn canonical_head(&self) -> Result<(Qualified, Oid), IdentityError> {
|
||||
// TODO: In the `fork` function for example, we call Repository::project_identity again,
|
||||
// This should only be necessary once.
|
||||
let (_, doc) = self.identity_doc()?;
|
||||
let doc = doc.verified()?;
|
||||
let project = doc.project()?;
|
||||
|
|
@ -601,7 +545,51 @@ impl ReadRepository for Repository {
|
|||
}
|
||||
|
||||
fn canonical_identity_head(&self) -> Result<Oid, IdentityError> {
|
||||
Repository::identity_head(self)
|
||||
let mut heads = Vec::new();
|
||||
|
||||
for remote in self.remote_ids()? {
|
||||
let remote = remote?;
|
||||
let oid = Doc::<Unverified>::head(&remote, self)?;
|
||||
|
||||
heads.push(oid.into());
|
||||
}
|
||||
// Keep track of the longest identity branch.
|
||||
let mut longest = heads.pop().ok_or(IdentityError::MissingBranch)?;
|
||||
|
||||
for head in &heads {
|
||||
let base = self.raw().merge_base(*head, longest)?;
|
||||
|
||||
if base == longest {
|
||||
// `head` is a successor of `longest`. Update `longest`.
|
||||
//
|
||||
// o head
|
||||
// |
|
||||
// o longest (base)
|
||||
// |
|
||||
//
|
||||
longest = *head;
|
||||
} else if base == *head || *head == longest {
|
||||
// `head` is an ancestor of `longest`, or equal to it. Do nothing.
|
||||
//
|
||||
// o longest o longest, head (base)
|
||||
// | |
|
||||
// o head (base) OR o
|
||||
// | |
|
||||
//
|
||||
} else {
|
||||
// The merge base between `head` and `longest` (`base`)
|
||||
// is neither `head` nor `longest`. Therefore, the branches have
|
||||
// diverged.
|
||||
//
|
||||
// longest head
|
||||
// \ /
|
||||
// o (base)
|
||||
// |
|
||||
//
|
||||
return Err(IdentityError::BranchesDiverge);
|
||||
}
|
||||
}
|
||||
Ok(longest.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue