evolution: replace Evolution trait by enum with Readonly and Mutable variants

This commit is contained in:
Martin von Zweigbergk 2021-01-31 18:13:37 -08:00
parent f1666375bd
commit d1e5f46969
4 changed files with 72 additions and 45 deletions

View file

@ -316,14 +316,39 @@ impl State {
}
}
pub trait Evolution {
fn successors(&self, commit_id: &CommitId) -> HashSet<CommitId>;
pub enum EvolutionRef<'a, 'm: 'a, 'r: 'm> {
Readonly(&'a ReadonlyEvolution<'r>),
Mutable(&'a MutableEvolution<'m, 'r>),
}
fn is_obsolete(&self, commit_id: &CommitId) -> bool;
impl EvolutionRef<'_, '_, '_> {
pub fn successors(&self, commit_id: &CommitId) -> HashSet<CommitId> {
match self {
EvolutionRef::Readonly(evolution) => evolution.successors(commit_id),
EvolutionRef::Mutable(evolution) => evolution.successors(commit_id),
}
}
fn is_orphan(&self, commit_id: &CommitId) -> bool;
pub fn is_obsolete(&self, commit_id: &CommitId) -> bool {
match self {
EvolutionRef::Readonly(evolution) => evolution.is_obsolete(commit_id),
EvolutionRef::Mutable(evolution) => evolution.is_obsolete(commit_id),
}
}
fn is_divergent(&self, change_id: &ChangeId) -> bool;
pub fn is_orphan(&self, commit_id: &CommitId) -> bool {
match self {
EvolutionRef::Readonly(evolution) => evolution.is_orphan(commit_id),
EvolutionRef::Mutable(evolution) => evolution.is_orphan(commit_id),
}
}
pub fn is_divergent(&self, change_id: &ChangeId) -> bool {
match self {
EvolutionRef::Readonly(evolution) => evolution.is_divergent(change_id),
EvolutionRef::Mutable(evolution) => evolution.is_divergent(change_id),
}
}
/// Given a current parent, finds the new parent candidates. If the current
/// parent is not obsolete, then a singleton set of that commit will be
@ -340,7 +365,12 @@ pub trait Evolution {
/// change id as A). Then C is rebased to somewhere else and becomes C'.
/// We will choose that C' as effective successor even though it has a
/// different change id and is not a descendant of one that does.
fn new_parent(&self, old_parent_id: &CommitId) -> HashSet<CommitId>;
pub fn new_parent(&self, old_parent_id: &CommitId) -> HashSet<CommitId> {
match self {
EvolutionRef::Readonly(evolution) => evolution.new_parent(old_parent_id),
EvolutionRef::Mutable(evolution) => evolution.new_parent(old_parent_id),
}
}
}
pub struct ReadonlyEvolution<'r> {
@ -355,29 +385,6 @@ pub trait EvolveListener {
fn divergent_no_common_predecessor(&mut self, commit1: &Commit, commit2: &Commit);
}
impl Evolution for ReadonlyEvolution<'_> {
fn successors(&self, commit_id: &CommitId) -> HashSet<CommitId> {
self.get_state().successors(commit_id)
}
fn is_obsolete(&self, commit_id: &CommitId) -> bool {
self.get_state().is_obsolete(commit_id)
}
fn is_orphan(&self, commit_id: &CommitId) -> bool {
self.get_state().is_orphan(commit_id)
}
fn is_divergent(&self, change_id: &ChangeId) -> bool {
self.get_state().is_divergent(change_id)
}
fn new_parent(&self, old_parent_id: &CommitId) -> HashSet<CommitId> {
self.get_state()
.new_parent(self.repo.store(), old_parent_id)
}
}
impl<'r> ReadonlyEvolution<'r> {
pub fn new(repo: &'r ReadonlyRepo) -> Self {
ReadonlyEvolution {
@ -403,6 +410,27 @@ impl<'r> ReadonlyEvolution<'r> {
state: self.get_state().as_ref().clone(),
}
}
pub fn successors(&self, commit_id: &CommitId) -> HashSet<CommitId> {
self.get_state().successors(commit_id)
}
pub fn is_obsolete(&self, commit_id: &CommitId) -> bool {
self.get_state().is_obsolete(commit_id)
}
pub fn is_orphan(&self, commit_id: &CommitId) -> bool {
self.get_state().is_orphan(commit_id)
}
pub fn is_divergent(&self, change_id: &ChangeId) -> bool {
self.get_state().is_divergent(change_id)
}
pub fn new_parent(&self, old_parent_id: &CommitId) -> HashSet<CommitId> {
self.get_state()
.new_parent(self.repo.store(), old_parent_id)
}
}
pub struct MutableEvolution<'r: 'm, 'm> {
@ -410,29 +438,27 @@ pub struct MutableEvolution<'r: 'm, 'm> {
state: State,
}
impl Evolution for MutableEvolution<'_, '_> {
fn successors(&self, commit_id: &CommitId) -> HashSet<CommitId> {
impl MutableEvolution<'_, '_> {
pub fn successors(&self, commit_id: &CommitId) -> HashSet<CommitId> {
self.state.successors(commit_id)
}
fn is_obsolete(&self, commit_id: &CommitId) -> bool {
pub fn is_obsolete(&self, commit_id: &CommitId) -> bool {
self.state.is_obsolete(commit_id)
}
fn is_orphan(&self, commit_id: &CommitId) -> bool {
pub fn is_orphan(&self, commit_id: &CommitId) -> bool {
self.state.is_orphan(commit_id)
}
fn is_divergent(&self, change_id: &ChangeId) -> bool {
pub fn is_divergent(&self, change_id: &ChangeId) -> bool {
self.state.is_divergent(change_id)
}
fn new_parent(&self, old_parent_id: &CommitId) -> HashSet<CommitId> {
pub fn new_parent(&self, old_parent_id: &CommitId) -> HashSet<CommitId> {
self.state.new_parent(self.repo.store(), old_parent_id)
}
}
impl MutableEvolution<'_, '_> {
pub fn add_commit(&mut self, commit: &Commit) {
self.state.add_commit(commit);
}

View file

@ -22,7 +22,7 @@ use std::sync::{Arc, Mutex, MutexGuard};
use thiserror::Error;
use crate::commit_builder::{new_change_id, signature};
use crate::evolution::{Evolution, MutableEvolution, ReadonlyEvolution};
use crate::evolution::{EvolutionRef, MutableEvolution, ReadonlyEvolution};
use crate::git_store::GitStore;
use crate::index::ReadonlyIndex;
use crate::local_store::LocalStore;
@ -77,10 +77,10 @@ impl<'a, 'r> RepoRef<'a, 'r> {
}
}
pub fn evolution(&self) -> &'a dyn Evolution {
pub fn evolution(&self) -> EvolutionRef {
match self {
RepoRef::Readonly(repo) => repo.evolution(),
RepoRef::Mutable(repo) => repo.evolution(),
RepoRef::Readonly(repo) => EvolutionRef::Readonly(repo.evolution()),
RepoRef::Mutable(repo) => EvolutionRef::Mutable(repo.evolution()),
}
}
}
@ -406,8 +406,10 @@ impl<'r> MutableRepo<'r> {
self.view.take().unwrap()
}
pub fn evolution(&self) -> &dyn Evolution {
self.evolution.as_ref().unwrap()
pub fn evolution<'m>(&'m self) -> &MutableEvolution<'r, 'm> {
let evolution: &MutableEvolution<'static, 'static> = self.evolution.as_ref().unwrap();
let evolution: &MutableEvolution<'r, 'm> = unsafe { std::mem::transmute(evolution) };
evolution
}
pub fn evolution_mut<'m>(&'m mut self) -> &'m mut MutableEvolution<'r, 'm> {

View file

@ -13,7 +13,6 @@
// limitations under the License.
use jujube_lib::commit_builder::CommitBuilder;
use jujube_lib::evolution::Evolution;
use jujube_lib::repo::RepoRef;
use jujube_lib::store::CommitId;
use jujube_lib::testutils;

View file

@ -36,7 +36,7 @@ use jujube_lib::commit_builder::CommitBuilder;
use jujube_lib::conflicts;
use jujube_lib::dag_walk::{common_ancestor, topo_order_reverse, walk_ancestors};
use jujube_lib::evolution::evolve;
use jujube_lib::evolution::{Evolution, EvolveListener};
use jujube_lib::evolution::EvolveListener;
use jujube_lib::files;
use jujube_lib::files::DiffLine;
use jujube_lib::git;