@@ -198,19 +198,20 @@ impl SerializedDepGraph {
198198
199199 // `node_max` is the number of indices including empty nodes while `node_count`
200200 // is the number of actually encoded nodes.
201- let ( node_max, node_count, edge_count) =
202- d. with_position ( d. len ( ) - 3 * IntEncodedWithFixedSize :: ENCODED_SIZE , |d| {
201+ let ( node_max, node_count, edge_count, chunk_count ) =
202+ d. with_position ( d. len ( ) - 4 * IntEncodedWithFixedSize :: ENCODED_SIZE , |d| {
203203 debug ! ( "position: {:?}" , d. position( ) ) ;
204204 let node_max = IntEncodedWithFixedSize :: decode ( d) . 0 as usize ;
205205 let node_count = IntEncodedWithFixedSize :: decode ( d) . 0 as usize ;
206206 let edge_count = IntEncodedWithFixedSize :: decode ( d) . 0 as usize ;
207- ( node_max, node_count, edge_count)
207+ let chunk_count = IntEncodedWithFixedSize :: decode ( d) . 0 as usize ;
208+ ( node_max, node_count, edge_count, chunk_count)
208209 } ) ;
209210 debug ! ( "position: {:?}" , d. position( ) ) ;
210211
211212 debug ! ( ?node_count, ?edge_count) ;
212213
213- let graph_bytes = d. len ( ) - ( 3 * IntEncodedWithFixedSize :: ENCODED_SIZE ) - d. position ( ) ;
214+ let graph_bytes = d. len ( ) - ( 4 * IntEncodedWithFixedSize :: ENCODED_SIZE ) - d. position ( ) ;
214215
215216 let mut nodes = IndexVec :: from_elem_n (
216217 DepNode { kind : D :: DEP_KIND_NULL , hash : PackedFingerprint :: from ( Fingerprint :: ZERO ) } ,
@@ -232,36 +233,45 @@ impl SerializedDepGraph {
232233 let mut edge_list_data =
233234 Vec :: with_capacity ( graph_bytes - node_count * size_of :: < SerializedNodeHeader < D > > ( ) ) ;
234235
235- for _ in 0 ..node_count {
236- // Decode the header for this edge; the header packs together as many of the fixed-size
237- // fields as possible to limit the number of times we update decoder state.
238- let node_header =
239- SerializedNodeHeader :: < D > { bytes : d. read_array ( ) , _marker : PhantomData } ;
236+ for _ in 0 ..chunk_count {
237+ let mut current_index = d. read_u32 ( ) ;
240238
241- let index = node_header. index ( ) ;
239+ loop {
240+ // Decode the header for this edge; the header packs together as many of the fixed-size
241+ // fields as possible to limit the number of times we update decoder state.
242+ let node_header =
243+ SerializedNodeHeader :: < D > { bytes : d. read_array ( ) , _marker : PhantomData } ;
242244
243- let node = & mut nodes[ index] ;
244- // Make sure there's no duplicate indices in the dep graph.
245- assert ! ( node_header. node( ) . kind != D :: DEP_KIND_NULL && node. kind == D :: DEP_KIND_NULL ) ;
246- * node = node_header. node ( ) ;
245+ if node_header. node ( ) . kind == D :: DEP_KIND_NULL {
246+ break ;
247+ }
248+
249+ let index = SerializedDepNodeIndex :: from_u32 ( current_index) ;
250+ current_index += 1 ;
247251
248- fingerprints[ index] = node_header. fingerprint ( ) ;
252+ let node = & mut nodes[ index] ;
253+ // Make sure there's no duplicate indices in the dep graph.
254+ assert ! ( node. kind == D :: DEP_KIND_NULL ) ;
255+ * node = node_header. node ( ) ;
249256
250- // If the length of this node's edge list is small, the length is stored in the header.
251- // If it is not, we fall back to another decoder call.
252- let num_edges = node_header. len ( ) . unwrap_or_else ( || d. read_u32 ( ) ) ;
257+ fingerprints[ index] = node_header. fingerprint ( ) ;
253258
254- // The edges index list uses the same varint strategy as rmeta tables; we select the
255- // number of byte elements per-array not per-element. This lets us read the whole edge
256- // list for a node with one decoder call and also use the on-disk format in memory.
257- let edges_len_bytes = node_header. bytes_per_index ( ) * ( num_edges as usize ) ;
258- // The in-memory structure for the edges list stores the byte width of the edges on
259- // this node with the offset into the global edge data array.
260- let edges_header = node_header. edges_header ( & edge_list_data, num_edges) ;
259+ // If the length of this node's edge list is small, the length is stored in the header.
260+ // If it is not, we fall back to another decoder call.
261+ let num_edges = node_header. len ( ) . unwrap_or_else ( || d. read_u32 ( ) ) ;
261262
262- edge_list_data. extend ( d. read_raw_bytes ( edges_len_bytes) ) ;
263+ // The edges index list uses the same varint strategy as rmeta tables; we select the
264+ // number of byte elements per-array not per-element. This lets us read the whole edge
265+ // list for a node with one decoder call and also use the on-disk format in memory.
266+ let edges_len_bytes = node_header. bytes_per_index ( ) * ( num_edges as usize ) ;
267+ // The in-memory structure for the edges list stores the byte width of the edges on
268+ // this node with the offset into the global edge data array.
269+ let edges_header = node_header. edges_header ( & edge_list_data, num_edges) ;
263270
264- edge_list_indices[ index] = edges_header;
271+ edge_list_data. extend ( d. read_raw_bytes ( edges_len_bytes) ) ;
272+
273+ edge_list_indices[ index] = edges_header;
274+ }
265275 }
266276
267277 // When we access the edge list data, we do a fixed-size read from the edge list data then
@@ -312,10 +322,9 @@ impl SerializedDepGraph {
312322/// * In whatever bits remain, the length of the edge list for this node, if it fits
313323struct SerializedNodeHeader < D > {
314324 // 2 bytes for the DepNode
315- // 4 bytes for the index
316325 // 16 for Fingerprint in DepNode
317326 // 16 for Fingerprint in NodeInfo
318- bytes : [ u8 ; 38 ] ,
327+ bytes : [ u8 ; 34 ] ,
319328 _marker : PhantomData < D > ,
320329}
321330
@@ -325,7 +334,6 @@ struct Unpacked {
325334 len : Option < u32 > ,
326335 bytes_per_index : usize ,
327336 kind : DepKind ,
328- index : SerializedDepNodeIndex ,
329337 hash : PackedFingerprint ,
330338 fingerprint : Fingerprint ,
331339}
@@ -347,7 +355,6 @@ impl<D: Deps> SerializedNodeHeader<D> {
347355 #[ inline]
348356 fn new (
349357 node : & DepNode ,
350- index : DepNodeIndex ,
351358 fingerprint : Fingerprint ,
352359 edge_max_index : u32 ,
353360 edge_count : usize ,
@@ -369,11 +376,10 @@ impl<D: Deps> SerializedNodeHeader<D> {
369376 let hash: Fingerprint = node. hash . into ( ) ;
370377
371378 // Using half-open ranges ensures an unconditional panic if we get the magic numbers wrong.
372- let mut bytes = [ 0u8 ; 38 ] ;
379+ let mut bytes = [ 0u8 ; 34 ] ;
373380 bytes[ ..2 ] . copy_from_slice ( & head. to_le_bytes ( ) ) ;
374- bytes[ 2 ..6 ] . copy_from_slice ( & index. as_u32 ( ) . to_le_bytes ( ) ) ;
375- bytes[ 6 ..22 ] . copy_from_slice ( & hash. to_le_bytes ( ) ) ;
376- bytes[ 22 ..] . copy_from_slice ( & fingerprint. to_le_bytes ( ) ) ;
381+ bytes[ 2 ..18 ] . copy_from_slice ( & hash. to_le_bytes ( ) ) ;
382+ bytes[ 18 ..] . copy_from_slice ( & fingerprint. to_le_bytes ( ) ) ;
377383
378384 #[ cfg( debug_assertions) ]
379385 {
@@ -390,9 +396,8 @@ impl<D: Deps> SerializedNodeHeader<D> {
390396 #[ inline]
391397 fn unpack ( & self ) -> Unpacked {
392398 let head = u16:: from_le_bytes ( self . bytes [ ..2 ] . try_into ( ) . unwrap ( ) ) ;
393- let index = u32:: from_le_bytes ( self . bytes [ 2 ..6 ] . try_into ( ) . unwrap ( ) ) ;
394- let hash = self . bytes [ 6 ..22 ] . try_into ( ) . unwrap ( ) ;
395- let fingerprint = self . bytes [ 22 ..] . try_into ( ) . unwrap ( ) ;
399+ let hash = self . bytes [ 2 ..18 ] . try_into ( ) . unwrap ( ) ;
400+ let fingerprint = self . bytes [ 18 ..] . try_into ( ) . unwrap ( ) ;
396401
397402 let kind = head & mask ( Self :: KIND_BITS ) as u16 ;
398403 let bytes_per_index = ( head >> Self :: KIND_BITS ) & mask ( Self :: WIDTH_BITS ) as u16 ;
@@ -402,7 +407,6 @@ impl<D: Deps> SerializedNodeHeader<D> {
402407 len : len. checked_sub ( 1 ) ,
403408 bytes_per_index : bytes_per_index as usize + 1 ,
404409 kind : DepKind :: new ( kind) ,
405- index : SerializedDepNodeIndex :: from_u32 ( index) ,
406410 hash : Fingerprint :: from_le_bytes ( hash) . into ( ) ,
407411 fingerprint : Fingerprint :: from_le_bytes ( fingerprint) ,
408412 }
@@ -418,11 +422,6 @@ impl<D: Deps> SerializedNodeHeader<D> {
418422 self . unpack ( ) . bytes_per_index
419423 }
420424
421- #[ inline]
422- fn index ( & self ) -> SerializedDepNodeIndex {
423- self . unpack ( ) . index
424- }
425-
426425 #[ inline]
427426 fn fingerprint ( & self ) -> Fingerprint {
428427 self . unpack ( ) . fingerprint
@@ -451,15 +450,10 @@ struct NodeInfo {
451450}
452451
453452impl NodeInfo {
454- fn encode < D : Deps > ( & self , e : & mut MemEncoder , index : DepNodeIndex ) {
453+ fn encode < D : Deps > ( & self , e : & mut MemEncoder ) {
455454 let NodeInfo { ref node, fingerprint, ref edges } = * self ;
456- let header = SerializedNodeHeader :: < D > :: new (
457- node,
458- index,
459- fingerprint,
460- edges. max_index ( ) ,
461- edges. len ( ) ,
462- ) ;
455+ let header =
456+ SerializedNodeHeader :: < D > :: new ( node, fingerprint, edges. max_index ( ) , edges. len ( ) ) ;
463457 e. write_array ( header. bytes ) ;
464458
465459 if header. len ( ) . is_none ( ) {
@@ -483,7 +477,6 @@ impl NodeInfo {
483477 fn encode_promoted < D : Deps > (
484478 e : & mut MemEncoder ,
485479 node : & DepNode ,
486- index : DepNodeIndex ,
487480 fingerprint : Fingerprint ,
488481 prev_index : SerializedDepNodeIndex ,
489482 colors : & DepNodeColorMap ,
@@ -496,7 +489,7 @@ impl NodeInfo {
496489 let edge_max =
497490 edges. clone ( ) . map ( |i| colors. current ( i) . unwrap ( ) . as_u32 ( ) ) . max ( ) . unwrap_or ( 0 ) ;
498491
499- let header = SerializedNodeHeader :: < D > :: new ( node, index , fingerprint, edge_max, edge_count) ;
492+ let header = SerializedNodeHeader :: < D > :: new ( node, fingerprint, edge_max, edge_count) ;
500493 e. write_array ( header. bytes ) ;
501494
502495 if header. len ( ) . is_none ( ) {
@@ -529,6 +522,9 @@ struct LocalEncoderState {
529522 encoder : MemEncoder ,
530523 node_count : usize ,
531524 edge_count : usize ,
525+ chunk_count : usize ,
526+
527+ in_chunk : bool ,
532528
533529 /// Stores the number of times we've encoded each dep kind.
534530 kind_stats : Vec < u32 > ,
@@ -538,6 +534,7 @@ struct LocalEncoderResult {
538534 node_max : u32 ,
539535 node_count : usize ,
540536 edge_count : usize ,
537+ chunk_count : usize ,
541538
542539 /// Stores the number of times we've encoded each dep kind.
543540 kind_stats : Vec < u32 > ,
@@ -565,6 +562,8 @@ impl<D: Deps> EncoderState<D> {
565562 remaining_node_index : 0 ,
566563 edge_count : 0 ,
567564 node_count : 0 ,
565+ chunk_count : 0 ,
566+ in_chunk : false ,
568567 encoder : MemEncoder :: new ( ) ,
569568 kind_stats : iter:: repeat_n ( 0 , D :: DEP_KIND_MAX as usize + 1 ) . collect ( ) ,
570569 } )
@@ -573,6 +572,31 @@ impl<D: Deps> EncoderState<D> {
573572 }
574573 }
575574
575+ #[ inline]
576+ fn end_chunk ( & self , local : & mut LocalEncoderState ) {
577+ if !local. in_chunk {
578+ return ;
579+ }
580+ local. in_chunk = false ;
581+
582+ NodeInfo {
583+ node : DepNode { kind : D :: DEP_KIND_NULL , hash : Fingerprint :: ZERO . into ( ) } ,
584+ fingerprint : Fingerprint :: ZERO ,
585+ edges : EdgesVec :: new ( ) ,
586+ }
587+ . encode :: < D > ( & mut local. encoder ) ;
588+ }
589+
590+ #[ inline]
591+ fn start_chunk ( & self , local : & mut LocalEncoderState , first_index : u32 ) {
592+ if local. in_chunk {
593+ self . end_chunk ( local) ;
594+ }
595+ local. in_chunk = true ;
596+ local. chunk_count += 1 ;
597+ local. encoder . emit_u32 ( first_index) ;
598+ }
599+
576600 #[ inline]
577601 fn next_index ( & self , local : & mut LocalEncoderState ) -> DepNodeIndex {
578602 if local. remaining_node_index == 0 {
@@ -587,6 +611,8 @@ impl<D: Deps> EncoderState<D> {
587611 // Check that we'll stay within `u32`
588612 local. next_node_index . checked_add ( COUNT ) . unwrap ( ) ;
589613
614+ self . start_chunk ( local, local. next_node_index ) ;
615+
590616 local. remaining_node_index = COUNT ;
591617 }
592618
@@ -643,10 +669,13 @@ impl<D: Deps> EncoderState<D> {
643669
644670 #[ inline]
645671 fn flush_mem_encoder ( & self , local : & mut LocalEncoderState ) {
646- let data = & mut local. encoder . data ;
647- if data. len ( ) > 64 * 1024 {
648- self . file . lock ( ) . as_mut ( ) . unwrap ( ) . emit_raw_bytes ( & data[ ..] ) ;
649- data. clear ( ) ;
672+ if local. encoder . data . len ( ) > 64 * 1024 {
673+ self . end_chunk ( local) ;
674+ self . file . lock ( ) . as_mut ( ) . unwrap ( ) . emit_raw_bytes ( & local. encoder . data [ ..] ) ;
675+ local. encoder . data . clear ( ) ;
676+ if local. remaining_node_index > 0 {
677+ self . start_chunk ( local, local. next_node_index ) ;
678+ }
650679 }
651680 }
652681
@@ -658,7 +687,7 @@ impl<D: Deps> EncoderState<D> {
658687 record_graph : & Option < Lock < DepGraphQuery > > ,
659688 local : & mut LocalEncoderState ,
660689 ) {
661- node. encode :: < D > ( & mut local. encoder , index ) ;
690+ node. encode :: < D > ( & mut local. encoder ) ;
662691 self . flush_mem_encoder ( & mut * local) ;
663692 self . record (
664693 & node. node ,
@@ -690,7 +719,6 @@ impl<D: Deps> EncoderState<D> {
690719 let edge_count = NodeInfo :: encode_promoted :: < D > (
691720 & mut local. encoder ,
692721 node,
693- index,
694722 fingerprint,
695723 prev_index,
696724 colors,
@@ -719,6 +747,8 @@ impl<D: Deps> EncoderState<D> {
719747 let results = broadcast ( |_| {
720748 let mut local = self . local . borrow_mut ( ) ;
721749
750+ self . end_chunk ( & mut * local) ;
751+
722752 // Prevent more indices from being allocated on this thread.
723753 local. remaining_node_index = 0 ;
724754
@@ -730,6 +760,7 @@ impl<D: Deps> EncoderState<D> {
730760 node_max : local. next_node_index ,
731761 node_count : local. node_count ,
732762 edge_count : local. edge_count ,
763+ chunk_count : local. chunk_count ,
733764 }
734765 } ) ;
735766
@@ -740,11 +771,13 @@ impl<D: Deps> EncoderState<D> {
740771 let mut node_max = 0 ;
741772 let mut node_count = 0 ;
742773 let mut edge_count = 0 ;
774+ let mut chunk_count = 0 ;
743775
744776 for result in results {
745777 node_max = max ( node_max, result. node_max ) ;
746778 node_count += result. node_count ;
747779 edge_count += result. edge_count ;
780+ chunk_count += result. chunk_count ;
748781 for ( i, stat) in result. kind_stats . iter ( ) . enumerate ( ) {
749782 kind_stats[ i] += stat;
750783 }
@@ -762,6 +795,7 @@ impl<D: Deps> EncoderState<D> {
762795 IntEncodedWithFixedSize ( node_max. try_into ( ) . unwrap ( ) ) . encode ( & mut encoder) ;
763796 IntEncodedWithFixedSize ( node_count. try_into ( ) . unwrap ( ) ) . encode ( & mut encoder) ;
764797 IntEncodedWithFixedSize ( edge_count. try_into ( ) . unwrap ( ) ) . encode ( & mut encoder) ;
798+ IntEncodedWithFixedSize ( chunk_count. try_into ( ) . unwrap ( ) ) . encode ( & mut encoder) ;
765799 debug ! ( "position: {:?}" , encoder. position( ) ) ;
766800 // Drop the encoder so that nothing is written after the counts.
767801 let result = encoder. finish ( ) ;
0 commit comments