That way it's in line with 'graph::Position'
Showing the changes to git-commitgraph/src/file (4 of 6 files). Show all
Unified · Split
| @@ -1,10 +1,12 @@ | |||
| 1 | use crate::file::commit::Commit; | 1 | use crate::file::{self, commit::Commit, File, COMMIT_DATA_ENTRY_SIZE}; |
| 2 | use crate::file::{File, LexPosition, COMMIT_DATA_ENTRY_SIZE}; | ||
| 3 | use git_object::{borrowed, HashKind, SHA1_SIZE}; | 2 | use git_object::{borrowed, HashKind, SHA1_SIZE}; |
| 4 | use std::convert::{TryFrom, TryInto}; | 3 | use std::{ |
| 5 | use std::fmt::{Debug, Formatter}; | 4 | convert::{TryFrom, TryInto}, |
| 6 | use std::path::Path; | 5 | fmt::{Debug, Formatter}, |
| 6 | path::Path, | ||
| 7 | }; | ||
| 7 | 8 | ||
| 9 | /// Access | ||
| 8 | impl File { | 10 | impl File { |
| 9 | /// Returns the commit data for the commit located at the given lex position. | 11 | /// Returns the commit data for the commit located at the given lex position. |
| 10 | /// | 12 | /// |
| @@ -13,7 +15,7 @@ impl File { · 2 unmodified lines | |||
| 13 | /// # Panics | 15 | /// # Panics |
| 14 | /// | 16 | /// |
| 15 | /// Panics if `pos` is out of bounds. | 17 | /// Panics if `pos` is out of bounds. |
| 16 | pub fn commit_at(&self, pos: LexPosition) -> Commit<'_> { | 18 | pub fn commit_at(&self, pos: file::Position) -> Commit<'_> { |
| 17 | Commit::new(self, pos) | 19 | Commit::new(self, pos) |
| 18 | } | 20 | } |
| 19 | 21 | ||
| @@ -24,7 +26,7 @@ impl File { · 4 unmodified lines | |||
| 24 | // copied from git-odb/src/pack/index/access.rs | 26 | // copied from git-odb/src/pack/index/access.rs |
| 25 | /// Returns 20 bytes sha1 at the given index in our list of (sorted) sha1 hashes. | 27 | /// Returns 20 bytes sha1 at the given index in our list of (sorted) sha1 hashes. |
| 26 | /// The position ranges from 0 to self.num_commits() | 28 | /// The position ranges from 0 to self.num_commits() |
| 27 | pub fn id_at(&self, pos: LexPosition) -> borrowed::Id<'_> { | 29 | pub fn id_at(&self, pos: file::Position) -> borrowed::Id<'_> { |
| 28 | assert!( | 30 | assert!( |
| 29 | pos.0 < self.num_commits(), | 31 | pos.0 < self.num_commits(), |
| 30 | "expected lex position less than {}, got {}", | 32 | "expected lex position less than {}, got {}", |
| @@ -50,15 +52,15 @@ impl File { · 19 unmodified lines | |||
| 50 | } | 52 | } |
| 51 | 53 | ||
| 52 | pub fn iter_commits(&self) -> impl Iterator<Item = Commit<'_>> { | 54 | pub fn iter_commits(&self) -> impl Iterator<Item = Commit<'_>> { |
| 53 | (0..self.num_commits()).map(move |i| self.commit_at(LexPosition(i))) | 55 | (0..self.num_commits()).map(move |i| self.commit_at(file::Position(i))) |
| 54 | } | 56 | } |
| 55 | 57 | ||
| 56 | pub fn iter_ids(&self) -> impl Iterator<Item = borrowed::Id<'_>> { | 58 | pub fn iter_ids(&self) -> impl Iterator<Item = borrowed::Id<'_>> { |
| 57 | (0..self.num_commits()).map(move |i| self.id_at(LexPosition(i))) | 59 | (0..self.num_commits()).map(move |i| self.id_at(file::Position(i))) |
| 58 | } | 60 | } |
| 59 | 61 | ||
| 60 | // copied from git-odb/src/pack/index/access.rs | 62 | // copied from git-odb/src/pack/index/access.rs |
| 61 | pub fn lookup(&self, id: borrowed::Id<'_>) -> Option<LexPosition> { | 63 | pub fn lookup(&self, id: borrowed::Id<'_>) -> Option<file::Position> { |
| 62 | let first_byte = id.first_byte() as usize; | 64 | let first_byte = id.first_byte() as usize; |
| 63 | let mut upper_bound = self.fan[first_byte]; | 65 | let mut upper_bound = self.fan[first_byte]; |
| 64 | let mut lower_bound = if first_byte != 0 { self.fan[first_byte - 1] } else { 0 }; | 66 | let mut lower_bound = if first_byte != 0 { self.fan[first_byte - 1] } else { 0 }; |
| @@ -69,12 +71,12 @@ impl File { · 4 unmodified lines | |||
| 69 | // it should not be if the bytes match up and the type has no destructor. | 71 | // it should not be if the bytes match up and the type has no destructor. |
| 70 | while lower_bound < upper_bound { | 72 | while lower_bound < upper_bound { |
| 71 | let mid = (lower_bound + upper_bound) / 2; | 73 | let mid = (lower_bound + upper_bound) / 2; |
| 72 | let mid_sha = self.id_at(LexPosition(mid)); | 74 | let mid_sha = self.id_at(file::Position(mid)); |
| 73 | 75 | ||
| 74 | use std::cmp::Ordering::*; | 76 | use std::cmp::Ordering::*; |
| 75 | match id.cmp(&mid_sha) { | 77 | match id.cmp(&mid_sha) { |
| 76 | Less => upper_bound = mid, | 78 | Less => upper_bound = mid, |
| 77 | Equal => return Some(LexPosition(mid)), | 79 | Equal => return Some(file::Position(mid)), |
| 78 | Greater => lower_bound = mid + 1, | 80 | Greater => lower_bound = mid + 1, |
| 79 | } | 81 | } |
| 80 | } | 82 | } |
| @@ -83,7 +85,7 @@ impl File { · 2 unmodified lines | |||
| 83 | 85 | ||
| 84 | /// Returns the number of commits in this graph file. | 86 | /// Returns the number of commits in this graph file. |
| 85 | /// | 87 | /// |
| 86 | /// The maximum valid `LexPosition` that can be used with this file is one less than | 88 | /// The maximum valid `Lexfile::Position` that can be used with this file is one less than |
| 87 | /// `num_commits()`. | 89 | /// `num_commits()`. |
| 88 | pub fn num_commits(&self) -> u32 { | 90 | pub fn num_commits(&self) -> u32 { |
| 89 | self.fan[255] | 91 | self.fan[255] |
| @@ -96,7 +98,7 @@ impl File { · 6 unmodified lines | |||
| 96 | 98 | ||
| 97 | impl File { | 99 | impl File { |
| 98 | /// Returns the byte slice for the given commit in this file's Commit Data (CDAT) chunk. | 100 | /// Returns the byte slice for the given commit in this file's Commit Data (CDAT) chunk. |
| 99 | pub(crate) fn commit_data_bytes(&self, pos: LexPosition) -> &[u8] { | 101 | pub(crate) fn commit_data_bytes(&self, pos: file::Position) -> &[u8] { |
| 100 | assert!( | 102 | assert!( |
| 101 | pos.0 < self.num_commits(), | 103 | pos.0 < self.num_commits(), |
| 102 | "expected lex position less than {}, got {}", | 104 | "expected lex position less than {}, got {}", |
| @@ -1,11 +1,15 @@ | |||
| 1 | use crate::file::{File, LexPosition}; | 1 | use crate::{ |
| 2 | use crate::graph::Position; | 2 | file::{self, File}, |
| 3 | graph, | ||
| 4 | }; | ||
| 3 | use byteorder::{BigEndian, ByteOrder}; | 5 | use byteorder::{BigEndian, ByteOrder}; |
| 4 | use git_object::{borrowed, owned, SHA1_SIZE}; | 6 | use git_object::{borrowed, owned, SHA1_SIZE}; |
| 5 | use quick_error::quick_error; | 7 | use quick_error::quick_error; |
| 6 | use std::convert::{TryFrom, TryInto}; | 8 | use std::{ |
| 7 | use std::fmt::{Debug, Formatter}; | 9 | convert::{TryFrom, TryInto}, |
| 8 | use std::slice::Chunks; | 10 | fmt::{Debug, Formatter}, |
| 11 | slice::Chunks, | ||
| 12 | }; | ||
| 9 | 13 | ||
| 10 | quick_error! { | 14 | quick_error! { |
| 11 | #[derive(Debug)] | 15 | #[derive(Debug)] |
| @@ -41,7 +45,7 @@ const EXTENDED_EDGES_MASK: u32 = 0x8000_0000; · 29 unmodified lines | |||
| 41 | 45 | ||
| 42 | pub struct Commit<'a> { | 46 | pub struct Commit<'a> { |
| 43 | file: &'a File, | 47 | file: &'a File, |
| 44 | lex_pos: LexPosition, | 48 | lex_pos: file::Position, |
| 45 | // We can parse the below fields lazily if needed. | 49 | // We can parse the below fields lazily if needed. |
| 46 | commit_timestamp: u64, | 50 | commit_timestamp: u64, |
| 47 | generation: u32, | 51 | generation: u32, |
| @@ -51,7 +55,7 @@ pub struct Commit<'a> { · 3 unmodified lines | |||
| 51 | } | 55 | } |
| 52 | 56 | ||
| 53 | impl<'a> Commit<'a> { | 57 | impl<'a> Commit<'a> { |
| 54 | pub(crate) fn new(file: &'a File, pos: LexPosition) -> Self { | 58 | pub(crate) fn new(file: &'a File, pos: file::Position) -> Self { |
| 55 | let bytes = file.commit_data_bytes(pos); | 59 | let bytes = file.commit_data_bytes(pos); |
| 56 | Commit { | 60 | Commit { |
| 57 | file, | 61 | file, |
| @@ -79,7 +83,7 @@ impl<'a> Commit<'a> { · 21 unmodified lines | |||
| 79 | self.generation | 83 | self.generation |
| 80 | } | 84 | } |
| 81 | 85 | ||
| 82 | pub fn iter_parents(&'a self) -> impl Iterator<Item = Result<Position, Error>> + 'a { | 86 | pub fn iter_parents(&'a self) -> impl Iterator<Item = Result<graph::Position, Error>> + 'a { |
| 83 | // I didn't find a combinator approach that a) was as strict as ParentIterator, b) supported | 87 | // I didn't find a combinator approach that a) was as strict as ParentIterator, b) supported |
| 84 | // fuse-after-first-error behavior, and b) was significantly shorter or more understandable | 88 | // fuse-after-first-error behavior, and b) was significantly shorter or more understandable |
| 85 | // than ParentIterator. So here we are. | 89 | // than ParentIterator. So here we are. |
| @@ -93,7 +97,7 @@ impl<'a> Commit<'a> { · 7 unmodified lines | |||
| 93 | self.file.id_at(self.lex_pos) | 97 | self.file.id_at(self.lex_pos) |
| 94 | } | 98 | } |
| 95 | 99 | ||
| 96 | pub fn parent1(&self) -> Result<Option<Position>, Error> { | 100 | pub fn parent1(&self) -> Result<Option<graph::Position>, Error> { |
| 97 | self.iter_parents().next().transpose() | 101 | self.iter_parents().next().transpose() |
| 98 | } | 102 | } |
| 99 | 103 | ||
| @@ -131,7 +135,7 @@ pub struct ParentIterator<'a> { · 31 unmodified lines | |||
| 131 | } | 135 | } |
| 132 | 136 | ||
| 133 | impl<'a> Iterator for ParentIterator<'a> { | 137 | impl<'a> Iterator for ParentIterator<'a> { |
| 134 | type Item = Result<Position, Error>; | 138 | type Item = Result<graph::Position, Error>; |
| 135 | 139 | ||
| 136 | fn next(&mut self) -> Option<Self::Item> { | 140 | fn next(&mut self) -> Option<Self::Item> { |
| 137 | let state = std::mem::replace(&mut self.state, ParentIteratorState::Exhausted); | 141 | let state = std::mem::replace(&mut self.state, ParentIteratorState::Exhausted); |
| @@ -219,7 +223,7 @@ enum ParentIteratorState<'a> { · 81 unmodified lines | |||
| 219 | #[derive(Clone, Copy, Debug)] | 223 | #[derive(Clone, Copy, Debug)] |
| 220 | enum ParentEdge { | 224 | enum ParentEdge { |
| 221 | None, | 225 | None, |
| 222 | GraphPosition(Position), | 226 | GraphPosition(graph::Position), |
| 223 | ExtraEdgeIndex(u32), | 227 | ExtraEdgeIndex(u32), |
| 224 | } | 228 | } |
| 225 | 229 | ||
| @@ -231,7 +235,7 @@ impl ParentEdge { · 5 unmodified lines | |||
| 231 | if raw & EXTENDED_EDGES_MASK != 0 { | 235 | if raw & EXTENDED_EDGES_MASK != 0 { |
| 232 | ParentEdge::ExtraEdgeIndex(raw & !EXTENDED_EDGES_MASK) | 236 | ParentEdge::ExtraEdgeIndex(raw & !EXTENDED_EDGES_MASK) |
| 233 | } else { | 237 | } else { |
| 234 | ParentEdge::GraphPosition(Position(raw)) | 238 | ParentEdge::GraphPosition(graph::Position(raw)) |
| 235 | } | 239 | } |
| 236 | } | 240 | } |
| 237 | } | 241 | } |
| @@ -239,16 +243,16 @@ impl ParentEdge { · 1 unmodified line | |||
| 239 | const LAST_EXTENDED_EDGE_MASK: u32 = 0x8000_0000; | 243 | const LAST_EXTENDED_EDGE_MASK: u32 = 0x8000_0000; |
| 240 | 244 | ||
| 241 | enum ExtraEdge { | 245 | enum ExtraEdge { |
| 242 | Internal(Position), | 246 | Internal(graph::Position), |
| 243 | Last(Position), | 247 | Last(graph::Position), |
| 244 | } | 248 | } |
| 245 | 249 | ||
| 246 | impl ExtraEdge { | 250 | impl ExtraEdge { |
| 247 | pub fn from_raw(raw: u32) -> Self { | 251 | pub fn from_raw(raw: u32) -> Self { |
| 248 | if raw & LAST_EXTENDED_EDGE_MASK != 0 { | 252 | if raw & LAST_EXTENDED_EDGE_MASK != 0 { |
| 249 | Self::Last(Position(raw & !LAST_EXTENDED_EDGE_MASK)) | 253 | Self::Last(graph::Position(raw & !LAST_EXTENDED_EDGE_MASK)) |
| 250 | } else { | 254 | } else { |
| 251 | Self::Internal(Position(raw)) | 255 | Self::Internal(graph::Position(raw)) |
| 252 | } | 256 | } |
| 253 | } | 257 | } |
| 254 | } | 258 | } |
| @@ -4,9 +4,11 @@ use byteorder::{BigEndian, ByteOrder}; · 3 unmodified lines | |||
| 4 | use filebuffer::FileBuffer; | 4 | use filebuffer::FileBuffer; |
| 5 | use git_object::SHA1_SIZE; | 5 | use git_object::SHA1_SIZE; |
| 6 | use quick_error::quick_error; | 6 | use quick_error::quick_error; |
| 7 | use std::convert::{TryFrom, TryInto}; | 7 | use std::{ |
| 8 | use std::ops::Range; | 8 | convert::{TryFrom, TryInto}, |
| 9 | use std::path::Path; | 9 | ops::Range, |
| 10 | path::Path, | ||
| 11 | }; | ||
| 10 | 12 | ||
| 11 | type ChunkId = [u8; 4]; | 13 | type ChunkId = [u8; 4]; |
| 12 | 14 | ||
| @@ -1,15 +1,18 @@ | |||
| 1 | //! Operations on a single commit-graph file. | 1 | //! Operations on a single commit-graph file. |
| 2 | mod access; | 2 | mod access; |
| 3 | pub mod commit; | 3 | pub mod commit; |
| 4 | |||
| 4 | mod init; | 5 | mod init; |
| 6 | pub use init::Error; | ||
| 5 | 7 | ||
| 6 | pub use commit::Commit; | 8 | pub use commit::Commit; |
| 7 | use filebuffer::FileBuffer; | 9 | use filebuffer::FileBuffer; |
| 8 | use git_object::SHA1_SIZE; | 10 | use git_object::SHA1_SIZE; |
| 9 | pub use init::Error; | 11 | use std::{ |
| 10 | use std::fmt::{Display, Formatter}; | 12 | fmt::{Display, Formatter}, |
| 11 | use std::ops::Range; | 13 | ops::Range, |
| 12 | use std::path::PathBuf; | 14 | path::PathBuf, |
| 15 | }; | ||
| 13 | 16 | ||
| 14 | const COMMIT_DATA_ENTRY_SIZE: usize = SHA1_SIZE + 16; | 17 | const COMMIT_DATA_ENTRY_SIZE: usize = SHA1_SIZE + 16; |
| 15 | const FAN_LEN: usize = 256; | 18 | const FAN_LEN: usize = 256; |
| @@ -32,16 +35,16 @@ pub struct File { · 16 unmodified lines | |||
| 32 | 35 | ||
| 33 | /// The position of a given commit within a graph file, starting at 0. | 36 | /// The position of a given commit within a graph file, starting at 0. |
| 34 | /// | 37 | /// |
| 35 | /// Commits within a graph file are sorted in lexicographical order by OID; a commit's lex position | 38 | /// Commits within a graph file are sorted in lexicographical order by OID; a commit's lexigraphical position |
| 36 | /// is its position in this ordering. If a commit graph spans multiple files, each file's commits | 39 | /// is its position in this ordering. If a commit graph spans multiple files, each file's commits |
| 37 | /// start at lex position 0, so lex position is unique across a single file but is not unique across | 40 | /// start at lexigraphical position 0, so it is unique across a single file but is not unique across |
| 38 | /// the whole commit graph. Each commit also has a graph position (`GraphPosition`), which is unique | 41 | /// the whole commit graph. Each commit also has a graph position (`graph::Position`), which is unique |
| 39 | /// across the whole commit graph. In order to avoid accidentally mixing lex positions with graph | 42 | /// across the whole commit graph. In order to avoid accidentally mixing lexigraphical positions with graph |
| 40 | /// positions, distinct types are used for each. | 43 | /// positions, distinct types are used for each. |
| 41 | #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] | 44 | #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] |
| 42 | pub struct LexPosition(pub u32); | 45 | pub struct Position(pub u32); |
| 43 | 46 | ||
| 44 | impl Display for LexPosition { | 47 | impl Display for Position { |
| 45 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | 48 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
| 46 | self.0.fmt(f) | 49 | self.0.fmt(f) |
| 47 | } | 50 | } |