Skip to content

Commit

Permalink
rename oldest to earliest
Browse files Browse the repository at this point in the history
  • Loading branch information
AjithPanneerselvam committed Feb 4, 2025
1 parent e9f866b commit 6400d1d
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 159 deletions.
169 changes: 23 additions & 146 deletions lib/src/default_index/revset_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -974,9 +974,11 @@ impl EvaluationContext<'_> {
let candidate_set = self.evaluate(candidates)?;
Ok(Box::new(self.take_latest_revset(&*candidate_set, *count)?))
}
ResolvedExpression::Oldest { candidates, count } => {
ResolvedExpression::Earliest { candidates, count } => {
let candidate_set = self.evaluate(candidates)?;
Ok(Box::new(self.take_oldest_revset(&*candidate_set, *count)?))
Ok(Box::new(
self.take_earliest_revset(&*candidate_set, *count)?,
))
}
ResolvedExpression::Coalesce(expression1, expression2) => {
let set1 = self.evaluate(expression1)?;
Expand Down Expand Up @@ -1061,7 +1063,7 @@ impl EvaluationContext<'_> {
Ok(EagerRevset { positions })
}

fn take_oldest_revset(
fn take_earliest_revset(
&self,
candidate_set: &dyn InternalRevset,
count: usize,
Expand All @@ -1070,10 +1072,10 @@ impl EvaluationContext<'_> {
return Ok(EagerRevset::empty());
}

#[derive(Clone, Eq, PartialEq)]
#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
struct Item {
timestamp: MillisSinceEpoch,
pos: IndexPosition,
pos: IndexPosition, // tie-breaker
}

let make_rev_item = |pos| -> Result<_, RevsetEvaluationError> {
Expand All @@ -1085,156 +1087,31 @@ impl EvaluationContext<'_> {
})
};

let mut items: Vec<_> = candidate_set
// Maintain max-heap containing the earliest (smallest) count items.
let mut candidate_iter = candidate_set
.positions()
.attach(self.index)
.map(make_rev_item)
.try_collect()?;

// Sort by timestamp (oldest first), then by position
items.sort_by(|a, b| {
a.timestamp
.cmp(&b.timestamp)
.then_with(|| a.pos.cmp(&b.pos))
});
.fuse();
let mut earliest_items: BinaryHeap<_> =
candidate_iter.by_ref().take(count).try_collect()?;
for item in candidate_iter {
let item = item?;
let mut newest = earliest_items.peek_mut().unwrap();
if *newest > item {
*newest = item;
}
}

let _positions = items
assert!(earliest_items.len() <= count);
let mut positions = earliest_items
.into_iter()
.take(count)
.map(|item| item.pos)
.collect_vec();

Ok(EagerRevset::empty())
// Ok(EagerRevset { vec![]})
positions.sort_unstable_by_key(|&pos| Reverse(pos));
Ok(EagerRevset { positions })
}

// fn take_oldest_revset(
// &self,
// candidate_set: &dyn InternalRevset,
// count: usize,
// ) -> Result<EagerRevset, RevsetEvaluationError> {
// if count == 0 {
// return Ok(EagerRevset::empty());
// }

// #[derive(Clone, Eq, PartialEq)]
// struct Item {
// timestamp: MillisSinceEpoch,
// pos: IndexPosition,
// }

// // Implement Ord and PartialOrd to create a min-heap
// impl Ord for Item {
// fn cmp(&self, other: &Self) -> std::cmp::Ordering {
// other
// .timestamp
// .cmp(&self.timestamp)
// .then_with(|| other.pos.cmp(&self.pos))
// }
// }

// impl PartialOrd for Item {
// fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
// Some(self.cmp(other))
// }
// }

// let make_rev_item = |pos| -> Result<_, RevsetEvaluationError> {
// let entry = self.index.entry_by_pos(pos?);
// let commit = self.store.get_commit(&entry.commit_id())?;
// Ok(Item {
// timestamp: commit.committer().timestamp.timestamp,
// pos: entry.position(),
// })
// };

// let mut candidate_iter = candidate_set
// .positions()
// .attach(self.index)
// .map(make_rev_item)
// .fuse();
// let mut oldest_items: BinaryHeap<_> = candidate_iter.by_ref().take(count).try_collect()?;
// for item in candidate_iter {
// let item = item?;
// if oldest_items.len() < count {
// oldest_items.push(item);
// } else if item < *oldest_items.peek().unwrap() {
// oldest_items.pop();
// oldest_items.push(item);
// }
// }

// assert!(oldest_items.len() <= count);
// let mut positions = oldest_items.into_iter().map(|item| item.pos).collect_vec();
// positions.sort_unstable();
// Ok(EagerRevset { positions })
// }

// fn take_oldest_revset(
// &self,
// candidate_set: &dyn InternalRevset,
// count: usize,
// ) -> Result<EagerRevset, RevsetEvaluationError> {
// if count == 0 {
// return Ok(EagerRevset::empty());
// }

// #[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
// struct Item {
// timestamp: MillisSinceEpoch,
// pos: IndexPosition, // tie-breaker
// }

// let make_rev_item = |pos| -> Result<_, RevsetEvaluationError> {
// let entry = self.index.entry_by_pos(pos?);
// let commit = self.store.get_commit(&entry.commit_id())?;
// Ok(Reverse(Item {
// timestamp: commit.committer().timestamp.timestamp,
// pos: entry.position(),
// }))
// // Ok(Item {
// // timestamp: commit.committer().timestamp.timestamp,
// // pos: entry.position(),
// // })
// };

// // Maintain min-heap containing the oldest (smallest) count items. For small
// // count and large candidate set, this is probably cheaper than building vec
// // and applying selection algorithm.
// let mut candidate_iter = candidate_set
// .positions()
// .attach(self.index)
// .map(make_rev_item)
// .fuse();
// let mut oldest_items: BinaryHeap<_> = candidate_iter.by_ref().take(count).try_collect()?;
// for item in candidate_iter {
// let item = item?;
// let mut latest = oldest_items.peek_mut().unwrap();
// if item.0 < latest.0 {
// *latest = item;
// }
// // if latest.pos.0 < item.pos.0 {
// // *latest = item;
// // }
// }

// assert!(oldest_items.len() <= count);
// // let mut positions = oldest_items
// // .into_iter()
// // .map(|item| item.pos.0)
// // .collect_vec();
// // positions.sort_unstable();
// // Ok(EagerRevset { positions })

// let mut positions = oldest_items
// .into_iter()
// .map(|item| item.0.pos)
// .collect_vec();
// // positions.sort_unstable();
// positions.sort_unstable_by_key(|&pos| pos);
// Ok(EagerRevset { positions })
// }

fn take_latest_revset(
&self,
candidate_set: &dyn InternalRevset,
Expand Down
35 changes: 22 additions & 13 deletions lib/src/revset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ pub enum RevsetExpression<St: ExpressionState> {
candidates: Rc<Self>,
count: usize,
},
Oldest {
Earliest {
candidates: Rc<Self>,
count: usize,
},
Expand Down Expand Up @@ -380,8 +380,8 @@ impl<St: ExpressionState> RevsetExpression<St> {
})
}

pub fn oldest(self: &Rc<Self>, count: usize) -> Rc<Self> {
Rc::new(Self::Oldest {
pub fn earliest(self: &Rc<Self>, count: usize) -> Rc<Self> {
Rc::new(Self::Earliest {
candidates: self.clone(),
count,
})
Expand Down Expand Up @@ -643,7 +643,7 @@ pub enum ResolvedExpression {
candidates: Box<Self>,
count: usize,
},
Oldest {
Earliest {
candidates: Box<Self>,
count: usize,
},
Expand Down Expand Up @@ -833,15 +833,15 @@ static BUILTIN_FUNCTION_MAP: Lazy<HashMap<&'static str, RevsetFunction>> = Lazy:
};
Ok(candidates.latest(count))
});
map.insert("oldest", |diagnostics, function, context| {
map.insert("earliest", |diagnostics, function, context| {
let ([candidates_arg], [count_opt_arg]) = function.expect_arguments()?;
let candidates = lower_expression(diagnostics, candidates_arg, context)?;
let count = if let Some(count_arg) = count_opt_arg {
expect_literal(diagnostics, "integer", count_arg)?
} else {
1
};
Ok(candidates.latest(count))
Ok(candidates.earliest(count))
});
map.insert("fork_point", |diagnostics, function, context| {
let [expression_arg] = function.expect_exact_arguments()?;
Expand Down Expand Up @@ -1335,11 +1335,12 @@ fn try_transform_expression<St: ExpressionState, E>(
candidates,
count: *count,
}),
RevsetExpression::Oldest { candidates, count } => transform_rec(candidates, pre, post)?
.map(|candidates| RevsetExpression::Latest {
RevsetExpression::Earliest { candidates, count } => {
transform_rec(candidates, pre, post)?.map(|candidates| RevsetExpression::Earliest {
candidates,
count: *count,
}),
})
}
RevsetExpression::Filter(_) => None,
RevsetExpression::AsFilter(candidates) => {
transform_rec(candidates, pre, post)?.map(RevsetExpression::AsFilter)
Expand Down Expand Up @@ -1534,10 +1535,10 @@ where
let count = *count;
RevsetExpression::Latest { candidates, count }.into()
}
RevsetExpression::Oldest { candidates, count } => {
RevsetExpression::Earliest { candidates, count } => {
let candidates = folder.fold_expression(candidates)?;
let count = *count;
RevsetExpression::Oldest { candidates, count }.into()
RevsetExpression::Earliest { candidates, count }.into()
}
RevsetExpression::Filter(predicate) => RevsetExpression::Filter(predicate.clone()).into(),
RevsetExpression::AsFilter(candidates) => {
Expand Down Expand Up @@ -2423,7 +2424,7 @@ impl VisibilityResolutionContext<'_> {
candidates: self.resolve(candidates).into(),
count: *count,
},
RevsetExpression::Oldest { candidates, count } => ResolvedExpression::Oldest {
RevsetExpression::Earliest { candidates, count } => ResolvedExpression::Earliest {
candidates: self.resolve(candidates).into(),
count: *count,
},
Expand Down Expand Up @@ -2529,7 +2530,7 @@ impl VisibilityResolutionContext<'_> {
| RevsetExpression::Roots(_)
| RevsetExpression::ForkPoint(_)
| RevsetExpression::Latest { .. }
| RevsetExpression::Oldest { .. } => {
| RevsetExpression::Earliest { .. } => {
ResolvedPredicateExpression::Set(self.resolve(expression).into())
}
RevsetExpression::Filter(predicate) => {
Expand Down Expand Up @@ -3577,6 +3578,14 @@ mod tests {
}
"###);

insta::assert_debug_snapshot!(
optimize(parse("earliest(bookmarks() & all(), 2)").unwrap()), @r###"
Latest {
candidates: CommitRef(Bookmarks(Substring(""))),
count: 2,
}
"###);

insta::assert_debug_snapshot!(
optimize(parse("present(foo ~ bar)").unwrap()), @r###"
Present(
Expand Down

0 comments on commit 6400d1d

Please sign in to comment.