| @@ -41,7 +41,6 @@ impl<'repo> Tree<'repo> { · 40 unmodified lines |
| 41 | 41 | |
| 42 | 42 | /// Follow a sequence of `path` components starting from this instance, and look them up one by one until the last component |
| 43 | 43 | /// is looked up and its tree entry is returned. |
| 44 | | − /// Use `buf` as temporary location for sub-trees to avoid allocating a temporary buffer for each lookup. |
| 45 | 44 | /// |
| 46 | 45 | /// # Performance Notes |
| 47 | 46 | /// |
| @@ -49,16 +48,18 @@ impl<'repo> Tree<'repo> { · 1 unmodified line |
| 49 | 48 | /// to reuse a vector and use a binary search instead, which might be able to improve performance over all. |
| 50 | 49 | /// However, a benchmark should be created first to have some data and see which trade-off to choose here. |
| 51 | 50 | /// |
| 52 | | − pub fn lookup_entry<I, P>(&self, path: I, buf: &mut Vec<u8>) -> Result<Option<Entry<'repo>>, find::existing::Error> |
| 51 | + pub fn lookup_entry<I, P>(&self, path: I) -> Result<Option<Entry<'repo>>, find::existing::Error> |
| 53 | 52 | where |
| 54 | 53 | I: IntoIterator<Item = P>, |
| 55 | 54 | P: PartialEq<BStr>, |
| 56 | 55 | { |
| 57 | | − let mut path = path.into_iter().peekable(); |
| 56 | + let mut buf = self.repo.shared_empty_buf(); |
| 58 | 57 | buf.clear(); |
| 58 | + |
| 59 | + let mut path = path.into_iter().peekable(); |
| 59 | 60 | buf.extend_from_slice(&self.data); |
| 60 | 61 | while let Some(component) = path.next() { |
| 61 | | − match TreeRefIter::from_bytes(buf) |
| 62 | + match TreeRefIter::from_bytes(&buf) |
| 62 | 63 | .filter_map(Result::ok) |
| 63 | 64 | .find(|entry| component.eq(entry.filename)) |
| 64 | 65 | { |
| @@ -70,7 +71,7 @@ impl<'repo> Tree<'repo> { · 5 unmodified lines |
| 70 | 71 | })); |
| 71 | 72 | } else { |
| 72 | 73 | let next_id = entry.oid.to_owned(); |
| 73 | | − let obj = self.repo.objects.find(&next_id, buf)?; |
| 74 | + let obj = self.repo.objects.find(&next_id, &mut buf)?; |
| 74 | 75 | if !obj.kind.is_tree() { |
| 75 | 76 | return Ok(None); |
| 76 | 77 | } |
| @@ -134,17 +135,13 @@ impl<'repo> Tree<'repo> { · 57 unmodified lines |
| 134 | 135 | pub fn lookup_entry_by_path( |
| 135 | 136 | &self, |
| 136 | 137 | relative_path: impl AsRef<std::path::Path>, |
| 137 | | − buf: &mut Vec<u8>, |
| 138 | 138 | ) -> Result<Option<Entry<'repo>>, find::existing::Error> { |
| 139 | 139 | use crate::bstr::ByteSlice; |
| 140 | | − self.lookup_entry( |
| 141 | | − relative_path.as_ref().components().map(|c: std::path::Component<'_>| { |
| 142 | | − gix_path::os_str_into_bstr(c.as_os_str()) |
| 143 | | − .unwrap_or_else(|_| "".into()) |
| 144 | | − .as_bytes() |
| 145 | | − }), |
| 146 | | − buf, |
| 147 | | − ) |
| 140 | + self.lookup_entry(relative_path.as_ref().components().map(|c: std::path::Component<'_>| { |
| 141 | + gix_path::os_str_into_bstr(c.as_os_str()) |
| 142 | + .unwrap_or_else(|_| "".into()) |
| 143 | + .as_bytes() |
| 144 | + })) |
| 148 | 145 | } |
| 149 | 146 | |
| 150 | 147 | /// Like [`Self::peel_to_entry()`], but takes a `Path` directly via `relative_path`, a path relative to this tree. |