@@ -6,12 +6,14 @@ use std::{
66 str:: from_utf8,
77} ;
88
9+ use futures:: AsyncReadExt ;
10+
911pub use crate :: constants:: { BLOB_KEY , INDEX_KEY , TREE_KEY } ;
1012pub use crate :: hash:: Hash ;
1113pub use crate :: header:: Header ;
1214pub use crate :: object:: Object ;
13- use crate :: object_body:: Object as ObjectTrait ;
1415pub use crate :: primitives:: { Mode , ObjectType } ;
16+ use crate :: { object_body:: Object as ObjectTrait , store:: Store } ;
1517
1618pub mod archive;
1719mod constants;
@@ -59,42 +61,89 @@ pub fn read_header_from_file(reader: &mut BufReader<File>) -> Option<Header> {
5961 read_header_from_slice ( & vec[ ..vec. len ( ) - 1 ] )
6062}
6163
62- pub fn read_object_into_headers (
63- cache : & PathBuf ,
64+ pub async fn read_object_into_headers (
65+ store : & Store ,
6466 headers : & mut HashMap < Hash , Header > ,
6567 object_hash : & Hash ,
6668) -> anyhow:: Result < ( ) > {
67- let object_path = object_hash. get_path ( & cache) ;
68- assert ! ( object_path. exists( ) ) ;
69+ let mut stack = vec ! [ object_hash. clone( ) ] ;
6970
70- // We assume that if our hash already exists, We probably have already collected all children
71- if headers. contains_key ( object_hash ) {
72- return Ok ( ( ) ) ;
73- }
71+ while let Some ( current_hash ) = stack . pop ( ) {
72+ if headers. contains_key ( & current_hash ) {
73+ continue ;
74+ }
7475
75- let file = File :: open ( object_path) . expect ( "file to exist" ) ;
76- let mut reader = BufReader :: new ( file) ;
77- let mut data = Vec :: new ( ) ;
78- let bytes_read = reader
79- . read_until ( 0 , & mut data)
80- . expect ( "File to be readable" ) ;
76+ let mut object = store. get_object ( & current_hash) . await ?;
8177
82- let header =
83- read_header_from_slice ( & data[ ..bytes_read - 1 ] ) . expect ( "File to be correctly formatted" ) ;
84- assert ! ( header. object_type != ObjectType :: Index ) ;
78+ if object. header . object_type == ObjectType :: Index {
79+ return Err ( anyhow:: anyhow!(
80+ "Indexes cannot exist within a tree. Likely a hash collision 😳"
81+ ) ) ;
82+ }
83+
84+ headers. insert ( current_hash. clone ( ) , object. header . clone ( ) ) ;
85+
86+ if object. header . object_type == ObjectType :: Blob {
87+ continue ;
88+ }
8589
86- headers. insert ( object_hash. clone ( ) , header. clone ( ) ) ;
87- if header. object_type == ObjectType :: Blob {
88- return Ok ( ( ) ) ;
90+ let mut data = Vec :: new ( ) ;
91+ let bytes_read = object. read_to_end ( & mut data) . await ?;
92+
93+ assert ! (
94+ bytes_read as u64 == object. header. size,
95+ "Read size must match header size"
96+ ) ;
97+
98+ let tree = crate :: object_body:: Tree :: from_data ( & data) ;
99+
100+ for entry in & tree. contents {
101+ stack. push ( entry. hash . clone ( ) ) ;
102+ }
89103 }
90104
91- reader. read_to_end ( & mut data) ?;
105+ Ok ( ( ) )
106+ }
107+
108+ pub fn read_object_into_headers_sync (
109+ cache : & PathBuf ,
110+ headers : & mut HashMap < Hash , Header > ,
111+ object_hash : & Hash ,
112+ ) -> anyhow:: Result < ( ) > {
113+ let mut stack = vec ! [ object_hash. clone( ) ] ;
92114
93- // println!("Reading Tree {object_hash}");
94- let tree = crate :: object_body:: Tree :: from_data ( & data[ bytes_read..] ) ;
115+ while let Some ( current_hash) = stack. pop ( ) {
116+ if headers. contains_key ( & current_hash) {
117+ continue ;
118+ }
119+
120+ let object_path = current_hash. get_path ( cache) ;
121+ let file = File :: open ( object_path) ?;
122+ let mut reader = BufReader :: new ( file) ;
123+ let mut data = Vec :: new ( ) ;
124+ let bytes_read = reader. read_until ( 0 , & mut data) ?;
95125
96- for entry in & tree. contents {
97- read_object_into_headers ( cache, headers, & entry. hash ) ?;
126+ let header = read_header_from_slice ( & data[ ..bytes_read - 1 ] )
127+ . ok_or_else ( || anyhow:: anyhow!( "Invalid header" ) ) ?;
128+
129+ if header. object_type == ObjectType :: Index {
130+ return Err ( anyhow:: anyhow!( "Indexes cannot exist within a tree" ) ) ;
131+ }
132+
133+ headers. insert ( current_hash. clone ( ) , header. clone ( ) ) ;
134+
135+ if header. object_type == ObjectType :: Blob {
136+ continue ;
137+ }
138+
139+ data. clear ( ) ;
140+ reader. read_to_end ( & mut data) ?;
141+
142+ let tree = crate :: object_body:: Tree :: from_data ( & data) ;
143+
144+ for entry in & tree. contents {
145+ stack. push ( entry. hash . clone ( ) ) ;
146+ }
98147 }
99148
100149 Ok ( ( ) )
0 commit comments