Skip to content

Commit 620d2e6

Browse files
committed
Extensions are optional, and so is their iteration (#293)
1 parent 5526020 commit 620d2e6

File tree

4 files changed

+44
-17
lines changed

4 files changed

+44
-17
lines changed

git-index/src/decode.rs

+31-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{extension, State};
1+
use crate::{extension, Entry, State, Version};
22
use filetime::FileTime;
33
use git_hash::Kind;
44

@@ -79,10 +79,15 @@ impl State {
7979
// Note that we ignore all errors for optional signatures.
8080
match start_of_extensions {
8181
Some(offset) => {
82-
ext = load_extensions(&data[offset..], object_hash);
82+
let (ext, entries) =
83+
git_features::parallel::join(|| load_extensions(&data[offset..], object_hash), || ());
8384
todo!("load all extensions in thread, then get IEOT, then possibly multi-threaded entry parsing")
8485
}
85-
None => todo!("load entries singlge-threaded, then extensions"),
86+
None => {
87+
let (entries, data) = load_entries(version, data, num_entries, object_hash)?;
88+
let ext = load_extensions(data, object_hash);
89+
todo!("load entries singlge-threaded, then extensions")
90+
}
8691
}
8792

8893
Ok(State {
@@ -93,19 +98,31 @@ impl State {
9398
}
9499
}
95100

101+
fn load_entries(
102+
version: Version,
103+
beginning_of_entries: &[u8],
104+
num_entries: u32,
105+
object_hash: git_hash::Kind,
106+
) -> Result<(Vec<Entry>, &[u8]), Error> {
107+
todo!("load entries")
108+
}
109+
96110
fn load_extensions(beginning_of_extensions: &[u8], object_hash: git_hash::Kind) -> Extensions {
97-
let extensions = extension::Iter::new_without_checksum(beginning_of_extensions, object_hash);
98-
let mut ext = Extensions::default();
99-
for (signature, ext_data) in extensions {
100-
match signature {
101-
extension::tree::SIGNATURE => {
102-
ext.cache_tree = extension::tree::decode(ext_data, object_hash);
111+
extension::Iter::new_without_checksum(beginning_of_extensions, object_hash)
112+
.map(|extensions| {
113+
let mut ext = Extensions::default();
114+
for (signature, ext_data) in extensions {
115+
match signature {
116+
extension::tree::SIGNATURE => {
117+
ext.cache_tree = extension::tree::decode(ext_data, object_hash);
118+
}
119+
extension::end_of_index_entry::SIGNATURE => {} // skip already done
120+
_unknown => {} // skip unknown extensions, too
121+
}
103122
}
104-
extension::end_of_index_entry::SIGNATURE => {} // skip already done
105-
_unknown => {} // skip unknown extensions, too
106-
}
107-
}
108-
ext
123+
ext
124+
})
125+
.unwrap_or_default()
109126
}
110127

111128
#[derive(Default)]

git-index/src/extension/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,17 @@ mod iter {
8484
}
8585
}
8686

87-
pub fn new_without_checksum(data_at_beginning_of_extensions: &'a [u8], object_hash: git_hash::Kind) -> Self {
87+
pub fn new_without_checksum(
88+
data_at_beginning_of_extensions: &'a [u8],
89+
object_hash: git_hash::Kind,
90+
) -> Option<Self> {
8891
let end = data_at_beginning_of_extensions
8992
.len()
90-
.checked_sub(object_hash.len_in_bytes())
91-
.expect("someone asserted that there is at least one extension");
93+
.checked_sub(object_hash.len_in_bytes())?;
9294
Iter {
9395
data: &data_at_beginning_of_extensions[..end],
9496
}
97+
.into()
9598
}
9699
}
97100

git-index/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ pub enum Version {
5555
V4 = 4,
5656
}
5757

58+
/// An entry in the index, identifying a non-tree item on disk.
59+
pub struct Entry;
60+
5861
/// An index file whose state was read from a file on disk.
5962
pub struct File {
6063
pub state: State,

git-index/tests/file/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@ mod init {
1818
let file = file("v2_more_files");
1919
assert_eq!(file.version(), Version::V2);
2020
}
21+
22+
#[test]
23+
#[ignore]
24+
fn read_without_any_extension() {}
2125
}

0 commit comments

Comments
 (0)