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()
|
self.description().unwrap_or_default()
|
||||||
);
|
);
|
||||||
let current = doc.update(remote, &msg, &signatures.collect::<Vec<_>>(), repo.raw())?;
|
let current = doc.update(remote, &msg, &signatures.collect::<Vec<_>>(), repo.raw())?;
|
||||||
|
let head = repo.set_identity_head()?;
|
||||||
|
|
||||||
|
assert_eq!(head, current);
|
||||||
|
|
||||||
Ok(Identity {
|
Ok(Identity {
|
||||||
head: current,
|
head,
|
||||||
root: previous.root,
|
root: previous.root,
|
||||||
current,
|
current,
|
||||||
revision: previous.revision + 1,
|
revision: previous.revision + 1,
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,6 @@ pub fn fork<G: Signer, S: storage::WriteStorage>(
|
||||||
) -> Result<(), ForkError> {
|
) -> Result<(), ForkError> {
|
||||||
let me = signer.public_key();
|
let me = signer.public_key();
|
||||||
let repository = storage.repository_mut(rid)?;
|
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_id, _) = repository.identity_doc()?;
|
||||||
let (canonical_branch, canonical_head) = repository.head()?;
|
let (canonical_branch, canonical_head) = repository.head()?;
|
||||||
let raw = repository.raw();
|
let raw = repository.raw();
|
||||||
|
|
|
||||||
|
|
@ -310,64 +310,6 @@ impl Repository {
|
||||||
Ok(verified)
|
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(
|
pub fn remote_ids(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<impl Iterator<Item = Result<RemoteId, refs::Error>> + '_, git2::Error> {
|
) -> 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> {
|
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> {
|
fn head(&self) -> Result<(Qualified, Oid), IdentityError> {
|
||||||
|
|
@ -568,8 +514,6 @@ impl ReadRepository for Repository {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn canonical_head(&self) -> Result<(Qualified, Oid), IdentityError> {
|
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) = self.identity_doc()?;
|
||||||
let doc = doc.verified()?;
|
let doc = doc.verified()?;
|
||||||
let project = doc.project()?;
|
let project = doc.project()?;
|
||||||
|
|
@ -601,7 +545,51 @@ impl ReadRepository for Repository {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn canonical_identity_head(&self) -> Result<Oid, IdentityError> {
|
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