@@ -7,30 +7,81 @@ use gix_features::{progress::Progress, threading, zlib};
7
7
8
8
use crate :: {
9
9
cache:: delta:: {
10
- traverse:: {
11
- util:: { ItemSliceSend , Node } ,
12
- Context , Error ,
13
- } ,
10
+ traverse:: { util:: ItemSliceSync , Context , Error } ,
14
11
Item ,
15
12
} ,
16
13
data,
17
14
data:: EntryRange ,
18
15
} ;
19
16
17
+ mod node {
18
+ use crate :: cache:: delta:: { traverse:: util:: ItemSliceSync , Item } ;
19
+
20
+ /// An item returned by `iter_root_chunks`, allowing access to the `data` stored alongside nodes in a [`Tree`].
21
+ pub ( crate ) struct Node < ' a , T : Send > {
22
+ item : & ' a mut Item < T > ,
23
+ child_items : & ' a ItemSliceSync < ' a , Item < T > > ,
24
+ }
25
+
26
+ impl < ' a , T : Send > Node < ' a , T > {
27
+ /// SAFETY: The child_items must be unique among between users of the `ItemSliceSync`.
28
+ #[ allow( unsafe_code) ]
29
+ pub ( crate ) unsafe fn new ( item : & ' a mut Item < T > , child_items : & ' a ItemSliceSync < ' a , Item < T > > ) -> Self {
30
+ Node { item, child_items }
31
+ }
32
+ }
33
+
34
+ impl < ' a , T : Send > Node < ' a , T > {
35
+ /// Returns the offset into the pack at which the `Node`s data is located.
36
+ pub fn offset ( & self ) -> u64 {
37
+ self . item . offset
38
+ }
39
+
40
+ /// Returns the slice into the data pack at which the pack entry is located.
41
+ pub fn entry_slice ( & self ) -> crate :: data:: EntryRange {
42
+ self . item . offset ..self . item . next_offset
43
+ }
44
+
45
+ /// Returns the node data associated with this node.
46
+ pub fn data ( & mut self ) -> & mut T {
47
+ & mut self . item . data
48
+ }
49
+
50
+ /// Returns true if this node has children, e.g. is not a leaf in the tree.
51
+ pub fn has_children ( & self ) -> bool {
52
+ !self . item . children . is_empty ( )
53
+ }
54
+
55
+ /// Transform this `Node` into an iterator over its children.
56
+ ///
57
+ /// Children are `Node`s referring to pack entries whose base object is this pack entry.
58
+ pub fn into_child_iter ( self ) -> impl Iterator < Item = Node < ' a , T > > + ' a {
59
+ let children = self . child_items ;
60
+ // SAFETY: The index is a valid index into the children array.
61
+ // SAFETY: The resulting mutable pointer cannot be yielded by any other node.
62
+ #[ allow( unsafe_code) ]
63
+ self . item . children . iter ( ) . map ( move |& index| Node {
64
+ item : unsafe { children. get_mut ( index as usize ) } ,
65
+ child_items : children,
66
+ } )
67
+ }
68
+ }
69
+ }
70
+
20
71
pub ( crate ) struct State < ' items , F , MBFN , T : Send > {
21
72
pub delta_bytes : Vec < u8 > ,
22
73
pub fully_resolved_delta_bytes : Vec < u8 > ,
23
74
pub progress : Box < dyn Progress > ,
24
75
pub resolve : F ,
25
76
pub modify_base : MBFN ,
26
- pub child_items : ItemSliceSend < ' items , Item < T > > ,
77
+ pub child_items : & ' items ItemSliceSync < ' items , Item < T > > ,
27
78
}
28
79
29
80
#[ allow( clippy:: too_many_arguments) ]
30
81
pub ( crate ) fn deltas < T , F , MBFN , E , R > (
31
82
objects : gix_features:: progress:: StepShared ,
32
83
size : gix_features:: progress:: StepShared ,
33
- node : & mut Item < T > ,
84
+ item : & mut Item < T > ,
34
85
State {
35
86
delta_bytes,
36
87
fully_resolved_delta_bytes,
@@ -67,13 +118,10 @@ where
67
118
// each node is a base, and its children always start out as deltas which become a base after applying them.
68
119
// These will be pushed onto our stack until all are processed
69
120
let root_level = 0 ;
70
- let mut nodes: Vec < _ > = vec ! [ (
71
- root_level,
72
- Node {
73
- item: node,
74
- child_items: child_items. clone( ) ,
75
- } ,
76
- ) ] ;
121
+ // SAFETY: The child items are unique
122
+ #[ allow( unsafe_code) ]
123
+ let root_node = unsafe { node:: Node :: new ( item, child_items) } ;
124
+ let mut nodes: Vec < _ > = vec ! [ ( root_level, root_node) ] ;
77
125
while let Some ( ( level, mut base) ) = nodes. pop ( ) {
78
126
if should_interrupt. load ( Ordering :: Relaxed ) {
79
127
return Err ( Error :: Interrupted ) ;
@@ -186,13 +234,13 @@ where
186
234
/// system. Since this thread will take a controlling function, we may spawn one more than that. In threaded mode, we will finish
187
235
/// all remaining work.
188
236
#[ allow( clippy:: too_many_arguments) ]
189
- pub ( crate ) fn deltas_mt < T , F , MBFN , E , R > (
237
+ fn deltas_mt < T , F , MBFN , E , R > (
190
238
mut threads_to_create : isize ,
191
239
decompressed_bytes_by_pack_offset : BTreeMap < u64 , ( data:: Entry , u64 , Vec < u8 > ) > ,
192
240
objects : gix_features:: progress:: StepShared ,
193
241
size : gix_features:: progress:: StepShared ,
194
242
progress : & dyn Progress ,
195
- nodes : Vec < ( u16 , Node < ' _ , T > ) > ,
243
+ nodes : Vec < ( u16 , node :: Node < ' _ , T > ) > ,
196
244
resolve : F ,
197
245
resolve_data : & R ,
198
246
modify_base : MBFN ,
0 commit comments