12
12
13
13
use crate :: Context ;
14
14
use rayon:: prelude:: * ;
15
+ use std:: fmt:: Write as FmtWrite ;
15
16
use std:: fs:: { self , File } ;
16
17
use std:: io:: { self , Read , Write } ;
17
18
use std:: path:: PathBuf ;
18
- use std:: time:: Instant ;
19
+ use std:: time:: { Duration , Instant } ;
19
20
use xz2:: read:: XzDecoder ;
20
21
21
22
impl Context {
@@ -53,17 +54,18 @@ impl Context {
53
54
. par_iter ( )
54
55
. map ( |xz_path| {
55
56
println ! ( "recompressing {}..." , xz_path. display( ) ) ;
57
+ let file_start = Instant :: now ( ) ;
56
58
let gz_path = xz_path. with_extension ( "gz" ) ;
57
59
58
- let mut destinations: Vec < Box < dyn io:: Write > > = Vec :: new ( ) ;
60
+ let mut destinations: Vec < ( & str , Box < dyn io:: Write > ) > = Vec :: new ( ) ;
59
61
60
62
// Produce gzip if explicitly enabled or the destination file doesn't exist.
61
63
if recompress_gz || !gz_path. is_file ( ) {
62
64
let gz = File :: create ( gz_path) ?;
63
- destinations. push ( Box :: new ( flate2 :: write :: GzEncoder :: new (
64
- gz ,
65
- compression_level,
66
- ) ) ) ;
65
+ destinations. push ( (
66
+ "gz" ,
67
+ Box :: new ( flate2 :: write :: GzEncoder :: new ( gz , compression_level) ) ,
68
+ ) ) ;
67
69
}
68
70
69
71
// xz recompression with more aggressive settings than we want to take the time
@@ -105,10 +107,13 @@ impl Context {
105
107
xz2:: stream:: Stream :: new_stream_encoder ( & filters, xz2:: stream:: Check :: None )
106
108
. unwrap ( ) ;
107
109
let xz_out = File :: create ( & xz_recompressed) ?;
108
- destinations. push ( Box :: new ( xz2:: write:: XzEncoder :: new_stream (
109
- std:: io:: BufWriter :: new ( xz_out) ,
110
- stream,
111
- ) ) ) ;
110
+ destinations. push ( (
111
+ "xz" ,
112
+ Box :: new ( xz2:: write:: XzEncoder :: new_stream (
113
+ std:: io:: BufWriter :: new ( xz_out) ,
114
+ stream,
115
+ ) ) ,
116
+ ) ) ;
112
117
}
113
118
114
119
// We only decompress once and then write into each of the compressors before
@@ -119,16 +124,38 @@ impl Context {
119
124
// assumption though.
120
125
let mut decompressor = XzDecoder :: new ( File :: open ( xz_path) ?) ;
121
126
let mut buffer = vec ! [ 0u8 ; 4 * 1024 * 1024 ] ;
127
+ let mut decompress_time = Duration :: ZERO ;
128
+ let mut time_by_dest = vec ! [ Duration :: ZERO ; destinations. len( ) ] ;
122
129
loop {
130
+ let start = Instant :: now ( ) ;
123
131
let length = decompressor. read ( & mut buffer) ?;
132
+ decompress_time += start. elapsed ( ) ;
124
133
if length == 0 {
125
134
break ;
126
135
}
127
- for destination in destinations. iter_mut ( ) {
136
+ for ( idx, ( _, destination) ) in destinations. iter_mut ( ) . enumerate ( ) {
137
+ let start = std:: time:: Instant :: now ( ) ;
128
138
destination. write_all ( & buffer[ ..length] ) ?;
139
+ time_by_dest[ idx] += start. elapsed ( ) ;
129
140
}
130
141
}
131
142
143
+ let mut compression_times = String :: new ( ) ;
144
+ for ( idx, ( name, _) ) in destinations. iter ( ) . enumerate ( ) {
145
+ writeln ! (
146
+ compression_times,
147
+ ", {:.2?} {} compression" ,
148
+ time_by_dest[ idx] , name
149
+ ) ?;
150
+ }
151
+ println ! (
152
+ "recompressed {}: {:.2?} total, {:.2?} decompression{}" ,
153
+ xz_path. display( ) ,
154
+ file_start. elapsed( ) ,
155
+ decompress_time,
156
+ compression_times
157
+ ) ;
158
+
132
159
if recompress_xz {
133
160
fs:: rename ( & xz_recompressed, xz_path) ?;
134
161
}
0 commit comments