That way, the trait impls can optimize access to their data structures.
Showing the changes to git-diff/src (3 of 3 files). Show all
Unified · Split
| @@ -75,14 +75,14 @@ impl<'a> tree::Changes<'a> { · 74 unmodified lines | |||
| 75 | match (lhs_entries.next(), rhs_entries.next()) { | 75 | match (lhs_entries.next(), rhs_entries.next()) { |
| 76 | (None, None) => { | 76 | (None, None) => { |
| 77 | match state.trees.pop_front() { | 77 | match state.trees.pop_front() { |
| 78 | Some((None, Some(rhs))) => { | 78 | Some((None, Some(mut rhs))) => { |
| 79 | delegate.set_current_path(rhs.parent_path_id.clone()); | 79 | delegate.set_current_path(rhs.parent_path_id.take().expect("path-id is set")); |
| 80 | rhs_entries = peekable( | 80 | rhs_entries = peekable( |
| 81 | locate(&rhs.tree_id, &mut state.buf2).ok_or(Error::NotFound { oid: rhs.tree_id })?, | 81 | locate(&rhs.tree_id, &mut state.buf2).ok_or(Error::NotFound { oid: rhs.tree_id })?, |
| 82 | ); | 82 | ); |
| 83 | } | 83 | } |
| 84 | Some((Some(lhs), Some(rhs))) => { | 84 | Some((Some(mut lhs), Some(rhs))) => { |
| 85 | delegate.set_current_path(lhs.parent_path_id.clone()); | 85 | delegate.set_current_path(lhs.parent_path_id.take().expect("path-id is set in lhs")); |
| 86 | lhs_entries = peekable( | 86 | lhs_entries = peekable( |
| 87 | locate(&lhs.tree_id, &mut state.buf1).ok_or(Error::NotFound { oid: lhs.tree_id })?, | 87 | locate(&lhs.tree_id, &mut state.buf1).ok_or(Error::NotFound { oid: lhs.tree_id })?, |
| 88 | ); | 88 | ); |
| @@ -90,8 +90,8 @@ impl<'a> tree::Changes<'a> { · 1 unmodified line | |||
| 90 | locate(&rhs.tree_id, &mut state.buf2).ok_or(Error::NotFound { oid: rhs.tree_id })?, | 90 | locate(&rhs.tree_id, &mut state.buf2).ok_or(Error::NotFound { oid: rhs.tree_id })?, |
| 91 | ); | 91 | ); |
| 92 | } | 92 | } |
| 93 | Some((Some(lhs), None)) => { | 93 | Some((Some(mut lhs), None)) => { |
| 94 | delegate.set_current_path(lhs.parent_path_id.clone()); | 94 | delegate.set_current_path(lhs.parent_path_id.take().expect("path-id is set")); |
| 95 | lhs_entries = peekable( | 95 | lhs_entries = peekable( |
| 96 | locate(&lhs.tree_id, &mut state.buf1).ok_or(Error::NotFound { oid: lhs.tree_id })?, | 96 | locate(&lhs.tree_id, &mut state.buf1).ok_or(Error::NotFound { oid: lhs.tree_id })?, |
| 97 | ); | 97 | ); |
| @@ -144,7 +144,7 @@ fn delete_entry_schedule_recursion<R: tree::Visit>( · 46 unmodified lines | |||
| 144 | queue.push_back(( | 144 | queue.push_back(( |
| 145 | Some(TreeInfo { | 145 | Some(TreeInfo { |
| 146 | tree_id: entry.oid.to_owned(), | 146 | tree_id: entry.oid.to_owned(), |
| 147 | parent_path_id: path_id, | 147 | parent_path_id: Some(path_id), |
| 148 | }), | 148 | }), |
| 149 | None, | 149 | None, |
| 150 | )); | 150 | )); |
| @@ -174,7 +174,7 @@ fn add_entry_schedule_recursion<R: tree::Visit>( · 23 unmodified lines | |||
| 174 | None, | 174 | None, |
| 175 | Some(TreeInfo { | 175 | Some(TreeInfo { |
| 176 | tree_id: entry.oid.to_owned(), | 176 | tree_id: entry.oid.to_owned(), |
| 177 | parent_path_id: path_id, | 177 | parent_path_id: Some(path_id), |
| 178 | }), | 178 | }), |
| 179 | )) | 179 | )) |
| 180 | } | 180 | } |
| @@ -285,11 +285,11 @@ fn handle_lhs_and_rhs_with_equal_filenames<R: tree::Visit>( · 104 unmodified lines | |||
| 285 | queue.push_back(( | 285 | queue.push_back(( |
| 286 | Some(TreeInfo { | 286 | Some(TreeInfo { |
| 287 | tree_id: lhs.oid.to_owned(), | 287 | tree_id: lhs.oid.to_owned(), |
| 288 | parent_path_id: path_id.clone(), | 288 | parent_path_id: Some(path_id), |
| 289 | }), | 289 | }), |
| 290 | Some(TreeInfo { | 290 | Some(TreeInfo { |
| 291 | tree_id: rhs.oid.to_owned(), | 291 | tree_id: rhs.oid.to_owned(), |
| 292 | parent_path_id: path_id, | 292 | parent_path_id: None, |
| 293 | }), | 293 | }), |
| 294 | )); | 294 | )); |
| 295 | } | 295 | } |
| @@ -317,7 +317,7 @@ fn handle_lhs_and_rhs_with_equal_filenames<R: tree::Visit>( · 21 unmodified lines | |||
| 317 | None, | 317 | None, |
| 318 | Some(TreeInfo { | 318 | Some(TreeInfo { |
| 319 | tree_id: rhs.oid.to_owned(), | 319 | tree_id: rhs.oid.to_owned(), |
| 320 | parent_path_id: path_id, | 320 | parent_path_id: Some(path_id), |
| 321 | }), | 321 | }), |
| 322 | )); | 322 | )); |
| 323 | } | 323 | } |
| @@ -344,7 +344,7 @@ fn handle_lhs_and_rhs_with_equal_filenames<R: tree::Visit>( · 20 unmodified lines | |||
| 344 | queue.push_back(( | 344 | queue.push_back(( |
| 345 | Some(TreeInfo { | 345 | Some(TreeInfo { |
| 346 | tree_id: lhs.oid.to_owned(), | 346 | tree_id: lhs.oid.to_owned(), |
| 347 | parent_path_id: path_id, | 347 | parent_path_id: Some(path_id), |
| 348 | }), | 348 | }), |
| 349 | None, | 349 | None, |
| 350 | )); | 350 | )); |
| @@ -3,8 +3,8 @@ use git_object::immutable; · 2 unmodified lines | |||
| 3 | use std::collections::VecDeque; | 3 | use std::collections::VecDeque; |
| 4 | 4 | ||
| 5 | /// The state required to visit [Changes] to be instantiated with `State::default()`. | 5 | /// The state required to visit [Changes] to be instantiated with `State::default()`. |
| 6 | #[derive(Default, Clone)] | 6 | #[derive(Default)] |
| 7 | pub struct State<PathId: Default + Clone> { | 7 | pub struct State<PathId> { |
| 8 | buf1: Vec<u8>, | 8 | buf1: Vec<u8>, |
| 9 | buf2: Vec<u8>, | 9 | buf2: Vec<u8>, |
| 10 | trees: VecDeque<TreeInfoPair<PathId>>, | 10 | trees: VecDeque<TreeInfoPair<PathId>>, |
| @@ -12,13 +12,12 @@ pub struct State<PathId: Default + Clone> { · 1 unmodified line | |||
| 12 | 12 | ||
| 13 | type TreeInfoPair<PathId> = (Option<TreeInfo<PathId>>, Option<TreeInfo<PathId>>); | 13 | type TreeInfoPair<PathId> = (Option<TreeInfo<PathId>>, Option<TreeInfo<PathId>>); |
| 14 | 14 | ||
| 15 | #[derive(Clone)] | 15 | pub(crate) struct TreeInfo<PathId> { |
| 16 | pub(crate) struct TreeInfo<PathId: Clone> { | ||
| 17 | pub tree_id: ObjectId, | 16 | pub tree_id: ObjectId, |
| 18 | pub parent_path_id: PathId, | 17 | pub parent_path_id: Option<PathId>, |
| 19 | } | 18 | } |
| 20 | 19 | ||
| 21 | impl<P: Clone + Default> State<P> { | 20 | impl<P> State<P> { |
| 22 | fn clear(&mut self) { | 21 | fn clear(&mut self) { |
| 23 | self.trees.clear(); | 22 | self.trees.clear(); |
| 24 | self.buf1.clear(); | 23 | self.buf1.clear(); |
| @@ -52,9 +52,10 @@ impl Action { · 51 unmodified lines | |||
| 52 | /// to turn tree A into tree B. | 52 | /// to turn tree A into tree B. |
| 53 | pub trait Visit { | 53 | pub trait Visit { |
| 54 | /// A type capable of uniquely identifying paths in a tree. | 54 | /// A type capable of uniquely identifying paths in a tree. |
| 55 | type PathId: Clone + Default; | 55 | type PathId; |
| 56 | 56 | ||
| 57 | /// Sets the path associated with the given `id` so future calls to push and pop components affect it instead. | 57 | /// Sets the path associated with the given `id` so future calls to push and pop components affect it instead. |
| 58 | /// It will only ever be called once with a given `id`. | ||
| 58 | fn set_current_path(&mut self, id: Self::PathId); | 59 | fn set_current_path(&mut self, id: Self::PathId); |
| 59 | /// Append a `component` to the end of a path, which may be empty, and associate it with the returned path id. | 60 | /// Append a `component` to the end of a path, which may be empty, and associate it with the returned path id. |
| 60 | fn push_tracked_path_component(&mut self, component: &BStr) -> Self::PathId; | 61 | fn push_tracked_path_component(&mut self, component: &BStr) -> Self::PathId; |