Skip to content

Commit 32632e9

Browse files
cruesslerByron
authored andcommitted
Move lookup_entry, lookup_entry_by_path to TreeRefIter
Adapt functions to new context. This mostly means copying the implementation from `gix::types::Tree` and applying minor changes related to `buffer` being passed as an argument.
1 parent 1c6e4ae commit 32632e9

File tree

2 files changed

+47
-42
lines changed

2 files changed

+47
-42
lines changed

gix-object/src/tree/ref_iter.rs

+45-40
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,6 @@ impl<'a> TreeRefIter<'a> {
1111
pub fn from_bytes(data: &'a [u8]) -> TreeRefIter<'a> {
1212
TreeRefIter { data }
1313
}
14-
}
15-
16-
impl<'a> TreeRef<'a> {
17-
/// Deserialize a Tree from `data`.
18-
pub fn from_bytes(mut data: &'a [u8]) -> Result<TreeRef<'a>, crate::decode::Error> {
19-
let input = &mut data;
20-
match decode::tree.parse_next(input) {
21-
Ok(tag) => Ok(tag),
22-
Err(err) => Err(crate::decode::Error::with_err(err, input)),
23-
}
24-
}
25-
26-
/// Find an entry named `name` knowing if the entry is a directory or not, using a binary search.
27-
///
28-
/// Note that it's impossible to binary search by name alone as the sort order is special.
29-
pub fn bisect_entry(&self, name: &BStr, is_dir: bool) -> Option<EntryRef<'a>> {
30-
static NULL_HASH: gix_hash::ObjectId = gix_hash::Kind::shortest().null();
31-
32-
let search = EntryRef {
33-
mode: if is_dir {
34-
tree::EntryKind::Tree
35-
} else {
36-
tree::EntryKind::Blob
37-
}
38-
.into(),
39-
filename: name,
40-
oid: &NULL_HASH,
41-
};
42-
self.entries
43-
.binary_search_by(|e| e.cmp(&search))
44-
.ok()
45-
.map(|idx| self.entries[idx])
46-
}
4714

4815
/// Follow a sequence of `path` components starting from this instance, and look them up one by one until the last component
4916
/// is looked up and its tree entry is returned.
@@ -64,19 +31,24 @@ impl<'a> TreeRef<'a> {
6431
I: IntoIterator<Item = P>,
6532
P: PartialEq<BStr>,
6633
{
67-
let mut path = path.into_iter().peekable();
68-
let mut entries = self.entries.clone();
34+
buffer.clear();
6935

36+
let mut path = path.into_iter().peekable();
37+
buffer.extend_from_slice(&self.data);
7038
while let Some(component) = path.next() {
71-
match entries.iter().find(|entry| component.eq(entry.filename)) {
39+
match TreeRefIter::from_bytes(&buffer)
40+
.filter_map(Result::ok)
41+
.find(|entry| component.eq(entry.filename))
42+
{
7243
Some(entry) => {
7344
if path.peek().is_none() {
74-
return Ok(Some((*entry).into()));
45+
return Ok(Some(entry.into()));
7546
} else {
7647
let next_id = entry.oid.to_owned();
77-
let obj = odb.find_tree(&next_id, buffer)?;
78-
79-
entries = obj.entries;
48+
let obj = odb.find(&next_id, buffer)?;
49+
if !obj.kind.is_tree() {
50+
return Ok(None);
51+
}
8052
}
8153
}
8254
None => return Ok(None),
@@ -108,6 +80,39 @@ impl<'a> TreeRef<'a> {
10880
}),
10981
)
11082
}
83+
}
84+
85+
impl<'a> TreeRef<'a> {
86+
/// Deserialize a Tree from `data`.
87+
pub fn from_bytes(mut data: &'a [u8]) -> Result<TreeRef<'a>, crate::decode::Error> {
88+
let input = &mut data;
89+
match decode::tree.parse_next(input) {
90+
Ok(tag) => Ok(tag),
91+
Err(err) => Err(crate::decode::Error::with_err(err, input)),
92+
}
93+
}
94+
95+
/// Find an entry named `name` knowing if the entry is a directory or not, using a binary search.
96+
///
97+
/// Note that it's impossible to binary search by name alone as the sort order is special.
98+
pub fn bisect_entry(&self, name: &BStr, is_dir: bool) -> Option<EntryRef<'a>> {
99+
static NULL_HASH: gix_hash::ObjectId = gix_hash::Kind::shortest().null();
100+
101+
let search = EntryRef {
102+
mode: if is_dir {
103+
tree::EntryKind::Tree
104+
} else {
105+
tree::EntryKind::Blob
106+
}
107+
.into(),
108+
filename: name,
109+
oid: &NULL_HASH,
110+
};
111+
self.entries
112+
.binary_search_by(|e| e.cmp(&search))
113+
.ok()
114+
.map(|idx| self.entries[idx])
115+
}
111116

112117
/// Create an instance of the empty tree.
113118
///

gix-object/tests/object/tree/iter.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ fn lookup_entry_toplevel() -> crate::Result {
6464
let root_tree_id = hex_to_id("ff7e7d2aecae1c3fb15054b289a4c58aa65b8646");
6565

6666
let mut buf = Vec::new();
67-
let root_tree = odb.find_tree(&root_tree_id, &mut buf)?;
67+
let root_tree = odb.find_tree_iter(&root_tree_id, &mut buf)?;
6868

6969
let mut buf = Vec::new();
7070
let entry = root_tree.lookup_entry_by_path(&odb, &mut buf, "bin").unwrap().unwrap();
@@ -81,7 +81,7 @@ fn lookup_entry_nested_path() -> crate::Result {
8181
let root_tree_id = hex_to_id("ff7e7d2aecae1c3fb15054b289a4c58aa65b8646");
8282

8383
let mut buf = Vec::new();
84-
let root_tree = odb.find_tree(&root_tree_id, &mut buf)?;
84+
let root_tree = odb.find_tree_iter(&root_tree_id, &mut buf)?;
8585

8686
let mut buf = Vec::new();
8787
let entry = root_tree

0 commit comments

Comments
 (0)