gix_commitgraph/
access.rs1use crate::{file, file::Commit, File, Graph, Position};
2
3impl Graph {
5 pub fn commit_at(&self, pos: Position) -> Commit<'_> {
10 let r = self.lookup_by_pos(pos);
11 r.file.commit_at(r.pos)
12 }
13
14 pub fn object_hash(&self) -> gix_hash::Kind {
18 self.files.first().object_hash()
19 }
20
21 pub fn commit_by_id(&self, id: impl AsRef<gix_hash::oid>) -> Option<Commit<'_>> {
23 let r = self.lookup_by_id(id.as_ref())?;
24 Some(r.file.commit_at(r.file_pos))
25 }
26
27 pub fn id_at(&self, pos: Position) -> &gix_hash::oid {
32 let r = self.lookup_by_pos(pos);
33 r.file.id_at(r.pos)
34 }
35
36 pub fn iter_commits(&self) -> impl Iterator<Item = Commit<'_>> {
38 self.files.iter().flat_map(File::iter_commits)
39 }
40
41 pub fn iter_ids(&self) -> impl Iterator<Item = &gix_hash::oid> {
43 self.files.iter().flat_map(File::iter_ids)
44 }
45
46 pub fn lookup(&self, id: impl AsRef<gix_hash::oid>) -> Option<Position> {
48 Some(self.lookup_by_id(id.as_ref())?.graph_pos)
49 }
50
51 pub fn num_commits(&self) -> u32 {
53 self.files.iter().map(File::num_commits).sum()
54 }
55}
56
57impl Graph {
59 fn lookup_by_id(&self, id: &gix_hash::oid) -> Option<LookupByIdResult<'_>> {
60 let mut current_file_start = 0;
61 for file in &self.files {
62 if let Some(lex_pos) = file.lookup(id) {
63 return Some(LookupByIdResult {
64 file,
65 file_pos: lex_pos,
66 graph_pos: Position(current_file_start + lex_pos.0),
67 });
68 }
69 current_file_start += file.num_commits();
70 }
71 None
72 }
73
74 fn lookup_by_pos(&self, pos: Position) -> LookupByPositionResult<'_> {
75 let mut remaining = pos.0;
76 for (file_index, file) in self.files.iter().enumerate() {
77 match remaining.checked_sub(file.num_commits()) {
78 Some(v) => remaining = v,
79 None => {
80 return LookupByPositionResult {
81 file,
82 _file_index: file_index,
83 pos: file::Position(remaining),
84 }
85 }
86 }
87 }
88 panic!("graph position too large: {}", pos.0);
89 }
90}
91
92#[derive(Clone)]
93struct LookupByIdResult<'a> {
94 pub file: &'a File,
95 pub graph_pos: Position,
96 pub file_pos: file::Position,
97}
98
99#[derive(Clone)]
100struct LookupByPositionResult<'a> {
101 pub file: &'a File,
102 pub _file_index: usize,
103 pub pos: file::Position,
104}