ok/jj
1
0
Fork 0
forked from mirrors/jj

index: extract helper functions for id lookup in mutable table

Similar to the previous commit, these functions will be reused by the change id
lookup methods. The return value isn't cloned because resolve_id_prefix() will
return (key, value) pair, and the current caller doesn't need a cloned value.
This commit is contained in:
Yuya Nishihara 2024-02-12 11:39:55 +09:00
parent 000cb41c7e
commit 903f18acfd

View file

@ -334,32 +334,13 @@ impl IndexSegment for MutableIndexSegment {
&self,
commit_id: &CommitId,
) -> (Option<CommitId>, Option<CommitId>) {
let prev_id = self
.commit_lookup
.range((Bound::Unbounded, Bound::Excluded(commit_id)))
.next_back()
.map(|(id, _)| id.clone());
let next_id = self
.commit_lookup
.range((Bound::Excluded(commit_id), Bound::Unbounded))
.next()
.map(|(id, _)| id.clone());
(prev_id, next_id)
let (prev_id, next_id) = resolve_neighbor_ids(&self.commit_lookup, commit_id);
(prev_id.cloned(), next_id.cloned())
}
fn resolve_commit_id_prefix(&self, prefix: &HexPrefix) -> PrefixResolution<CommitId> {
let min_bytes_prefix = CommitId::from_bytes(prefix.min_prefix_bytes());
let mut matches = self
.commit_lookup
.range((Bound::Included(&min_bytes_prefix), Bound::Unbounded))
.map(|(id, _pos)| id)
.take_while(|&id| prefix.matches(id))
.fuse();
match (matches.next(), matches.next()) {
(Some(id), None) => PrefixResolution::SingleMatch(id.clone()),
(Some(_), Some(_)) => PrefixResolution::AmbiguousMatch,
(None, _) => PrefixResolution::NoMatch,
}
resolve_id_prefix(&self.commit_lookup, prefix, &min_bytes_prefix).map(|id| id.clone())
}
fn generation_number(&self, local_pos: LocalPosition) -> u32 {
@ -499,3 +480,35 @@ impl MutableIndex for DefaultMutableIndex {
self.0.merge_in(other.as_segment().clone());
}
}
fn resolve_neighbor_ids<'a, K: Ord, V>(
lookup_table: &'a BTreeMap<K, V>,
id: &K,
) -> (Option<&'a K>, Option<&'a K>) {
let prev_id = lookup_table
.range((Bound::Unbounded, Bound::Excluded(id)))
.next_back()
.map(|(id, _)| id);
let next_id = lookup_table
.range((Bound::Excluded(id), Bound::Unbounded))
.next()
.map(|(id, _)| id);
(prev_id, next_id)
}
fn resolve_id_prefix<'a, K: ObjectId + Ord, V>(
lookup_table: &'a BTreeMap<K, V>,
prefix: &HexPrefix,
min_bytes_prefix: &K,
) -> PrefixResolution<&'a K> {
let mut matches = lookup_table
.range((Bound::Included(min_bytes_prefix), Bound::Unbounded))
.map(|(id, _pos)| id)
.take_while(|&id| prefix.matches(id))
.fuse();
match (matches.next(), matches.next()) {
(Some(id), None) => PrefixResolution::SingleMatch(id),
(Some(_), Some(_)) => PrefixResolution::AmbiguousMatch,
(None, _) => PrefixResolution::NoMatch,
}
}