Skip to content

Commit

Permalink
Fix Var's commits so that after Revision
Browse files Browse the repository at this point in the history
increments, commits from the past revisions are lazely commited at
first measurement
  • Loading branch information
zetanumbers committed Jan 5, 2021
1 parent ef032ec commit cfa7bec
Showing 1 changed file with 21 additions and 22 deletions.
43 changes: 21 additions & 22 deletions src/runtime/var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use super::{Revision, RevisionControlSystem};
pub(crate) struct Var<State> {
current: Commit<State>,
id: topo::CallId,
// can only contain commits from previous revisions
staged: Option<Commit<State>>,
// can only contain commit from current revision
// make proper checks inside methods!
pending: Option<(Revision, Commit<State>)>,
rcs: Arc<RwLock<RevisionControlSystem>>,
}
Expand All @@ -22,27 +22,21 @@ impl<State> Var<State> {
inner: State,
) -> Arc<Mutex<Self>> {
let current = Commit { id, inner: Arc::new(inner) };
Arc::new(Mutex::new(Var { id, current, rcs, staged: None, pending: None }))
Arc::new(Mutex::new(Var { id, current, rcs, pending: None }))
}

/// Attach this `Var` to its callsite, performing any pending commit and
/// returning the resulting latest commit.
pub fn root(var: Arc<Mutex<Self>>) -> (Commit<State>, Key<State>) {
let (id, commit_at_root) = {
let mut var = var.lock();
// This function is always called within it's context
let current = Revision::current();

// stage pending commit if it's from previous revision
match var.pending {
Some((revision, _)) if revision < current => {
var.staged = var.pending.take().map(|(_r, c)| c)
}
_ => (),
}

// perform staged commit
if let Some(staged) = var.staged.take() {
var.current = staged;
// Replace current commit with pending commit if it is from the past revision
match var.pending.take() {
Some((revision, commit)) if revision < current => var.current = commit,
still_pending => var.pending = still_pending,
}

(var.id, var.current.clone())
Expand All @@ -53,15 +47,19 @@ impl<State> Var<State> {

/// Returns a reference to the latest value, pending or committed.
pub fn latest(&self) -> &State {
self.pending
.as_ref()
.map(|(_revision, ref commit)| commit)
.or_else(|| self.staged.as_ref())
.unwrap_or(&self.current)
self.pending.as_ref().map(|(_r, c)| c).unwrap_or(&self.current)
}

///
pub fn current_commit(&self) -> &Commit<State> {
/// Returns a reference to the current commit.
pub fn current_commit(&mut self) -> &Commit<State> {
let current = self.rcs.read().revision;

// Replace current commit with pending commit if it is from the past revision
match self.pending.take() {
Some((revision, commit)) if revision < current => self.current = commit,
still_pending => self.pending = still_pending,
}

&self.current
}

Expand All @@ -73,8 +71,9 @@ impl<State> Var<State> {
let rcs_read = self.rcs.read();
let current = rcs_read.revision;

// Replace current commit with pending commit if it is from the past revision
match self.pending.replace((current, new_commit)) {
Some((revision, old_commit)) if revision < current => self.staged = Some(old_commit),
Some((revision, old_commit)) if revision < current => self.current = old_commit,
_ => (),
}

Expand Down

0 comments on commit cfa7bec

Please sign in to comment.