repo: make MutableRepo have an Arc<ReadonlyRepo> instead of a reference

I suspect that at least one reason that I didn't make
`MutableRepo::base_repo` by an `Arc<ReadonlyRepo>` before was that I
thought that that would mean that `start_transaction()` would need be
moved off of `ReadonlyRepo` so it can be given an
`&Arc<ReadonlyRepo>`, which would make it much less convenient to
use. It turns out that a `self` argument can actually be of type
`&Arc<ReadonlyRepo>`.
This commit is contained in:
Martin von Zweigbergk 2021-04-11 09:13:00 -07:00
parent 394c9ce82b
commit 783e1f6512
6 changed files with 53 additions and 53 deletions

View file

@ -154,7 +154,7 @@ impl CommitBuilder {
self
}
pub fn write_to_new_transaction(self, repo: &ReadonlyRepo, description: &str) -> Commit {
pub fn write_to_new_transaction(self, repo: &Arc<ReadonlyRepo>, description: &str) -> Commit {
let mut tx = repo.start_transaction(description);
let commit = self.write_to_repo(tx.mut_repo());
tx.commit();

View file

@ -64,20 +64,20 @@ pub type RepoResult<T> = Result<T, RepoError>;
// TODO: Should we implement From<&ReadonlyRepo> and From<&MutableRepo> for
// RepoRef?
#[derive(Clone, Copy)]
pub enum RepoRef<'a, 'r: 'a> {
pub enum RepoRef<'a> {
Readonly(&'a ReadonlyRepo),
Mutable(&'a MutableRepo<'r>),
Mutable(&'a MutableRepo),
}
impl<'a, 'r> RepoRef<'a, 'r> {
pub fn store(&self) -> &'a Arc<StoreWrapper> {
impl<'a> RepoRef<'a> {
pub fn store(&self) -> &Arc<StoreWrapper> {
match self {
RepoRef::Readonly(repo) => repo.store(),
RepoRef::Mutable(repo) => repo.store(),
}
}
pub fn op_store(&self) -> &'a Arc<dyn OpStore> {
pub fn op_store(&self) -> &Arc<dyn OpStore> {
match self {
RepoRef::Readonly(repo) => repo.op_store(),
RepoRef::Mutable(repo) => repo.op_store(),
@ -346,9 +346,14 @@ impl ReadonlyRepo {
&self.settings
}
pub fn start_transaction(&self, description: &str) -> Transaction {
pub fn start_transaction(self: &Arc<ReadonlyRepo>, description: &str) -> Transaction {
let locked_evolution = self.evolution.lock().unwrap();
let mut_repo = MutableRepo::new(self, self.index(), &self.view, locked_evolution.as_ref());
let mut_repo = MutableRepo::new(
self.clone(),
self.index(),
&self.view,
locked_evolution.as_ref(),
);
Transaction::new(mut_repo, description)
}
@ -469,20 +474,20 @@ impl RepoLoader {
}
}
pub struct MutableRepo<'r> {
base_repo: &'r ReadonlyRepo,
pub struct MutableRepo {
base_repo: Arc<ReadonlyRepo>,
index: MutableIndex,
view: MutableView,
evolution: Mutex<Option<MutableEvolution>>,
}
impl<'r> MutableRepo<'r> {
impl MutableRepo {
pub fn new(
base_repo: &'r ReadonlyRepo,
base_repo: Arc<ReadonlyRepo>,
index: Arc<ReadonlyIndex>,
view: &ReadonlyView,
evolution: Option<&Arc<ReadonlyEvolution>>,
) -> Arc<MutableRepo<'r>> {
) -> Arc<MutableRepo> {
let mut_view = view.start_modification();
let mut_index = MutableIndex::incremental(index);
let mut_evolution = evolution.map(|evolution| evolution.start_modification());
@ -498,8 +503,8 @@ impl<'r> MutableRepo<'r> {
RepoRef::Mutable(&self)
}
pub fn base_repo(&self) -> &'r ReadonlyRepo {
self.base_repo
pub fn base_repo(&self) -> &Arc<ReadonlyRepo> {
&self.base_repo
}
pub fn store(&self) -> &Arc<StoreWrapper> {

View file

@ -21,16 +21,16 @@ use crate::operation::Operation;
use crate::repo::{MutableRepo, ReadonlyRepo};
use crate::store::Timestamp;
pub struct Transaction<'r> {
repo: Option<Arc<MutableRepo<'r>>>,
pub struct Transaction {
repo: Option<Arc<MutableRepo>>,
parents: Vec<OperationId>,
description: String,
start_time: Timestamp,
closed: bool,
}
impl<'r> Transaction<'r> {
pub fn new(mut_repo: Arc<MutableRepo<'r>>, description: &str) -> Transaction<'r> {
impl Transaction {
pub fn new(mut_repo: Arc<MutableRepo>, description: &str) -> Transaction {
let parents = vec![mut_repo.base_repo().op_id().clone()];
Transaction {
repo: Some(mut_repo),
@ -41,7 +41,7 @@ impl<'r> Transaction<'r> {
}
}
pub fn base_repo(&self) -> &'r ReadonlyRepo {
pub fn base_repo(&self) -> &ReadonlyRepo {
self.repo.as_ref().unwrap().base_repo()
}
@ -49,7 +49,7 @@ impl<'r> Transaction<'r> {
self.parents = parents;
}
pub fn mut_repo(&mut self) -> &mut MutableRepo<'r> {
pub fn mut_repo(&mut self) -> &mut MutableRepo {
Arc::get_mut(self.repo.as_mut().unwrap()).unwrap()
}
@ -63,7 +63,7 @@ impl<'r> Transaction<'r> {
/// operation will not be seen when loading the repo at head.
pub fn write(mut self) -> UnpublishedOperation {
let mut_repo = Arc::try_unwrap(self.repo.take().unwrap()).ok().unwrap();
let base_repo = mut_repo.base_repo();
let base_repo = mut_repo.base_repo().clone();
let (mut_index, mut_view) = mut_repo.consume();
let index = base_repo.index_store().write_index(mut_index).unwrap();
@ -97,7 +97,7 @@ impl<'r> Transaction<'r> {
}
}
impl Drop for Transaction<'_> {
impl Drop for Transaction {
fn drop(&mut self) {
if !std::thread::panicking() {
debug_assert!(self.closed, "Transaction was dropped without being closed.");

View file

@ -16,6 +16,7 @@ use std::fs::OpenOptions;
use std::io::Write;
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
use std::sync::Arc;
use jujube_lib::commit_builder::CommitBuilder;
use jujube_lib::repo::ReadonlyRepo;
@ -73,7 +74,7 @@ fn test_checkout_file_transitions(use_git: bool) {
fn write_path(
settings: &UserSettings,
repo: &ReadonlyRepo,
repo: &Arc<ReadonlyRepo>,
tree_builder: &mut TreeBuilder,
kind: Kind,
path: &str,

View file

@ -213,10 +213,7 @@ impl<'a, I: 'a> Property<'a, I> {
}
}
fn parse_commit_keyword<'a, 'r: 'a>(
repo: RepoRef<'a, 'r>,
pair: Pair<Rule>,
) -> (Property<'a, Commit>, String) {
fn parse_commit_keyword<'a>(repo: RepoRef<'a>, pair: Pair<Rule>) -> (Property<'a, Commit>, String) {
assert_eq!(pair.as_rule(), Rule::identifier);
let property = match pair.as_str() {
"description" => Property::String(Box::new(DescriptionProperty)),
@ -257,8 +254,8 @@ fn coerce_to_string<'a, I: 'a>(
}
}
fn parse_boolean_commit_property<'a, 'r: 'a>(
repo: RepoRef<'a, 'r>,
fn parse_boolean_commit_property<'a>(
repo: RepoRef<'a>,
pair: Pair<Rule>,
) -> Box<dyn TemplateProperty<Commit, bool> + 'a> {
let mut inner = pair.into_inner();
@ -274,10 +271,7 @@ fn parse_boolean_commit_property<'a, 'r: 'a>(
}
}
fn parse_commit_term<'a, 'r: 'a>(
repo: RepoRef<'a, 'r>,
pair: Pair<Rule>,
) -> Box<dyn Template<Commit> + 'a> {
fn parse_commit_term<'a>(repo: RepoRef<'a>, pair: Pair<Rule>) -> Box<dyn Template<Commit> + 'a> {
assert_eq!(pair.as_rule(), Rule::term);
if pair.as_str().is_empty() {
Box::new(LiteralTemplate(String::new()))
@ -371,8 +365,8 @@ fn parse_commit_term<'a, 'r: 'a>(
}
}
fn parse_commit_template_rule<'a, 'r: 'a>(
repo: RepoRef<'a, 'r>,
fn parse_commit_template_rule<'a>(
repo: RepoRef<'a>,
pair: Pair<Rule>,
) -> Box<dyn Template<Commit> + 'a> {
match pair.as_rule() {
@ -394,8 +388,8 @@ fn parse_commit_template_rule<'a, 'r: 'a>(
}
}
pub fn parse_commit_template<'a, 'r: 'a>(
repo: RepoRef<'a, 'r>,
pub fn parse_commit_template<'a>(
repo: RepoRef<'a>,
template_text: &str,
) -> Box<dyn Template<Commit> + 'a> {
let mut pairs: Pairs<Rule> = TemplateParser::parse(Rule::template, template_text).unwrap();

View file

@ -206,21 +206,21 @@ impl TemplateProperty<Commit, bool> for PrunedProperty {
}
}
pub struct CurrentCheckoutProperty<'a, 'r> {
pub repo: RepoRef<'a, 'r>,
pub struct CurrentCheckoutProperty<'a> {
pub repo: RepoRef<'a>,
}
impl TemplateProperty<Commit, bool> for CurrentCheckoutProperty<'_, '_> {
impl TemplateProperty<Commit, bool> for CurrentCheckoutProperty<'_> {
fn extract(&self, context: &Commit) -> bool {
context.id() == self.repo.view().checkout()
}
}
pub struct GitRefsProperty<'a, 'r> {
pub repo: RepoRef<'a, 'r>,
pub struct GitRefsProperty<'a> {
pub repo: RepoRef<'a>,
}
impl TemplateProperty<Commit, String> for GitRefsProperty<'_, '_> {
impl TemplateProperty<Commit, String> for GitRefsProperty<'_> {
fn extract(&self, context: &Commit) -> String {
let refs: Vec<_> = self
.repo
@ -234,31 +234,31 @@ impl TemplateProperty<Commit, String> for GitRefsProperty<'_, '_> {
}
}
pub struct ObsoleteProperty<'a, 'r> {
pub repo: RepoRef<'a, 'r>,
pub struct ObsoleteProperty<'a> {
pub repo: RepoRef<'a>,
}
impl TemplateProperty<Commit, bool> for ObsoleteProperty<'_, '_> {
impl TemplateProperty<Commit, bool> for ObsoleteProperty<'_> {
fn extract(&self, context: &Commit) -> bool {
self.repo.evolution().is_obsolete(context.id())
}
}
pub struct OrphanProperty<'a, 'r> {
pub repo: RepoRef<'a, 'r>,
pub struct OrphanProperty<'a> {
pub repo: RepoRef<'a>,
}
impl TemplateProperty<Commit, bool> for OrphanProperty<'_, '_> {
impl TemplateProperty<Commit, bool> for OrphanProperty<'_> {
fn extract(&self, context: &Commit) -> bool {
self.repo.evolution().is_orphan(context.id())
}
}
pub struct DivergentProperty<'a, 'r> {
pub repo: RepoRef<'a, 'r>,
pub struct DivergentProperty<'a> {
pub repo: RepoRef<'a>,
}
impl TemplateProperty<Commit, bool> for DivergentProperty<'_, '_> {
impl TemplateProperty<Commit, bool> for DivergentProperty<'_> {
fn extract(&self, context: &Commit) -> bool {
self.repo.evolution().is_divergent(context.change_id())
}