1
+ use std:: slice:: ChunksMut ;
1
2
use std:: sync:: atomic:: { AtomicBool , AtomicU64 , AtomicUsize , Ordering } ;
2
3
use std:: { io, marker:: PhantomData , path:: Path } ;
3
4
@@ -19,7 +20,7 @@ use crate::{
19
20
20
21
/// Calculates the changes that need to be applied to an `index` to match the state of the `worktree` and makes them
21
22
/// observable in `collector`, along with information produced by `compare` which gets to see blobs that may have changes, and
22
- /// `submodule` which can take a look at submodules in detail to produce status information.
23
+ /// `submodule` which can take a look at submodules in detail to produce status information (BASE version if its conflicting) .
23
24
/// `options` are used to configure the operation.
24
25
///
25
26
/// Note that `index` is updated with the latest seen stat information from the worktree, and its timestamp is adjusted to
85
86
) ;
86
87
let ( entries, path_backing) = index. entries_mut_and_pathbacking ( ) ;
87
88
let mut num_entries = entries. len ( ) ;
89
+ let entry_index_offset = range. start ;
88
90
let entries = & mut entries[ range] ;
89
91
90
92
let _span = gix_features:: trace:: detail!( "gix_status::index_as_worktree" ,
@@ -137,14 +139,21 @@ where
137
139
} ;
138
140
in_parallel_if (
139
141
|| true , // TODO: heuristic: when is parallelization not worth it? Git says 500 items per thread, but to 20 threads, we can be more fine-grained though.
140
- gix_features:: interrupt:: Iter :: new ( entries. chunks_mut ( chunk_size) , should_interrupt) ,
142
+ gix_features:: interrupt:: Iter :: new (
143
+ OffsetIter {
144
+ inner : entries. chunks_mut ( chunk_size) ,
145
+ offset : entry_index_offset,
146
+ } ,
147
+ should_interrupt,
148
+ ) ,
141
149
thread_limit,
142
150
new_state,
143
- |entries, ( state, blobdiff, submdule, find, pathspec) | {
151
+ |( entry_offset , entries) , ( state, blobdiff, submdule, find, pathspec) | {
144
152
entries
145
153
. iter_mut ( )
146
- . filter_map ( |entry| {
147
- let res = state. process ( entry, pathspec, blobdiff, submdule, find) ;
154
+ . enumerate ( )
155
+ . filter_map ( |( entry_index, entry) | {
156
+ let res = state. process ( entry, entry_offset + entry_index, pathspec, blobdiff, submdule, find) ;
148
157
count. fetch_add ( 1 , Ordering :: Relaxed ) ;
149
158
res
150
159
} )
@@ -198,12 +207,22 @@ struct State<'a, 'b> {
198
207
odb_reads : & ' a AtomicUsize ,
199
208
}
200
209
201
- type StatusResult < ' index , T , U > = Result < ( & ' index gix_index:: Entry , & ' index BStr , Option < Change < T , U > > , bool ) , Error > ;
210
+ type StatusResult < ' index , T , U > = Result <
211
+ (
212
+ & ' index gix_index:: Entry ,
213
+ usize ,
214
+ & ' index BStr ,
215
+ Option < Change < T , U > > ,
216
+ bool ,
217
+ ) ,
218
+ Error ,
219
+ > ;
202
220
203
221
impl < ' index > State < ' _ , ' index > {
204
222
fn process < T , U , Find , E1 , E2 > (
205
223
& mut self ,
206
224
entry : & ' index mut gix_index:: Entry ,
225
+ entry_index : usize ,
207
226
pathspec : & mut impl Pathspec ,
208
227
diff : & mut impl CompareBlobs < Output = T > ,
209
228
submodule : & mut impl SubmoduleStatus < Output = U , Error = E2 > ,
@@ -234,7 +253,7 @@ impl<'index> State<'_, 'index> {
234
253
return None ;
235
254
}
236
255
let status = self . compute_status ( & mut * entry, path, diff, submodule, find) ;
237
- Some ( status. map ( move |status| ( & * entry, path, status, conflict) ) )
256
+ Some ( status. map ( move |status| ( & * entry, entry_index , path, status, conflict) ) )
238
257
}
239
258
240
259
/// # On how racy-git is handled here
@@ -412,8 +431,8 @@ impl<'index, T, U, C: VisitEntry<'index, ContentChange = T, SubmoduleStatus = U>
412
431
413
432
fn feed ( & mut self , items : Self :: Input ) -> Result < Self :: FeedProduce , Self :: Error > {
414
433
for item in items {
415
- let ( entry, path, change, conflict) = item?;
416
- self . collector . visit_entry ( entry, path, change, conflict) ;
434
+ let ( entry, entry_index , path, change, conflict) = item?;
435
+ self . collector . visit_entry ( entry, entry_index , path, change, conflict) ;
417
436
}
418
437
Ok ( ( ) )
419
438
}
@@ -511,3 +530,19 @@ where
511
530
Ok ( out)
512
531
}
513
532
}
533
+
534
+ struct OffsetIter < ' a , T > {
535
+ inner : ChunksMut < ' a , T > ,
536
+ offset : usize ,
537
+ }
538
+
539
+ impl < ' a , T > Iterator for OffsetIter < ' a , T > {
540
+ type Item = ( usize , & ' a mut [ T ] ) ;
541
+
542
+ fn next ( & mut self ) -> Option < Self :: Item > {
543
+ let block = self . inner . next ( ) ?;
544
+ let offset = self . offset ;
545
+ self . offset += block. len ( ) ;
546
+ Some ( ( offset, block) )
547
+ }
548
+ }
0 commit comments