summaryrefslogtreecommitdiffstats
path: root/vendor/gix-commitgraph/src/access.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /vendor/gix-commitgraph/src/access.rs
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-commitgraph/src/access.rs')
-rw-r--r--vendor/gix-commitgraph/src/access.rs97
1 files changed, 97 insertions, 0 deletions
diff --git a/vendor/gix-commitgraph/src/access.rs b/vendor/gix-commitgraph/src/access.rs
new file mode 100644
index 000000000..ce3688f78
--- /dev/null
+++ b/vendor/gix-commitgraph/src/access.rs
@@ -0,0 +1,97 @@
+use crate::{file, file::Commit, File, Graph, Position};
+
+/// Access
+impl Graph {
+ /// Returns the commit at the given position `pos`.
+ ///
+ /// # Panics
+ /// If `pos` is greater or equal to [`num_commits()`][Graph::num_commits()].
+ pub fn commit_at(&self, pos: Position) -> Commit<'_> {
+ let r = self.lookup_by_pos(pos);
+ r.file.commit_at(r.pos)
+ }
+
+ /// Returns the commit matching the given `id`.
+ pub fn commit_by_id(&self, id: impl AsRef<gix_hash::oid>) -> Option<Commit<'_>> {
+ let r = self.lookup_by_id(id.as_ref())?;
+ Some(r.file.commit_at(r.file_pos))
+ }
+
+ /// Returns the `hash` at the given position `pos`.
+ ///
+ /// # Panics
+ /// If `pos` is greater or equal to [`num_commits()`][Graph::num_commits()].
+ pub fn id_at(&self, pos: Position) -> &gix_hash::oid {
+ let r = self.lookup_by_pos(pos);
+ r.file.id_at(r.pos)
+ }
+
+ /// Iterate over commits in unsorted order.
+ pub fn iter_commits(&self) -> impl Iterator<Item = Commit<'_>> {
+ self.files.iter().flat_map(|file| file.iter_commits())
+ }
+
+ /// Iterate over commit IDs in unsorted order.
+ pub fn iter_ids(&self) -> impl Iterator<Item = &gix_hash::oid> {
+ self.files.iter().flat_map(|file| file.iter_ids())
+ }
+
+ /// Translate the given `id` to its position in the file.
+ pub fn lookup(&self, id: impl AsRef<gix_hash::oid>) -> Option<Position> {
+ Some(self.lookup_by_id(id.as_ref())?.graph_pos)
+ }
+
+ /// Returns the number of commits stored in this file.
+ pub fn num_commits(&self) -> u32 {
+ self.files.iter().map(|f| f.num_commits()).sum()
+ }
+}
+
+/// Access fundamentals
+impl Graph {
+ fn lookup_by_id(&self, id: &gix_hash::oid) -> Option<LookupByIdResult<'_>> {
+ let mut current_file_start = 0;
+ for file in &self.files {
+ if let Some(lex_pos) = file.lookup(id) {
+ return Some(LookupByIdResult {
+ file,
+ file_pos: lex_pos,
+ graph_pos: Position(current_file_start + lex_pos.0),
+ });
+ }
+ current_file_start += file.num_commits();
+ }
+ None
+ }
+
+ fn lookup_by_pos(&self, pos: Position) -> LookupByPositionResult<'_> {
+ let mut remaining = pos.0;
+ for (file_index, file) in self.files.iter().enumerate() {
+ match remaining.checked_sub(file.num_commits()) {
+ Some(v) => remaining = v,
+ None => {
+ return LookupByPositionResult {
+ file,
+ _file_index: file_index,
+ pos: file::Position(remaining),
+ }
+ }
+ }
+ }
+ panic!("graph position too large: {}", pos.0);
+ }
+}
+
+#[derive(Clone)]
+struct LookupByIdResult<'a> {
+ pub file: &'a File,
+ pub graph_pos: Position,
+ pub file_pos: file::Position,
+}
+
+#[derive(Clone)]
+struct LookupByPositionResult<'a> {
+ pub file: &'a File,
+ pub _file_index: usize,
+ pub pos: file::Position,
+}