@@ -124,18 +124,15 @@ def __init__(self,
124
124
self .raw = fp
125
125
self .level = level
126
126
self .previous_block = b""
127
- self .crc_queue : queue .Queue [bytes ] = queue .Queue (
128
- maxsize = threads * queue_size )
129
127
self .input_queues : List [queue .Queue [Tuple [bytes , memoryview ]]] = [
130
128
queue .Queue (queue_size ) for _ in range (threads )]
131
- self .output_queues : List [queue .Queue [bytes ]] = [
129
+ self .output_queues : List [queue .Queue [Tuple [ bytes , int , int ] ]] = [
132
130
queue .Queue (queue_size ) for _ in range (threads )]
133
131
self .index = 0
134
132
self .threads = threads
135
133
self ._crc = 0
136
134
self .running = False
137
135
self ._size = 0
138
- self .crc_worker = threading .Thread (target = self ._calculate_crc )
139
136
self .output_worker = threading .Thread (target = self ._write )
140
137
self .compression_workers = [
141
138
threading .Thread (target = self ._compress , args = (i ,))
@@ -159,15 +156,13 @@ def _write_gzip_header(self):
159
156
160
157
def start (self ):
161
158
self .running = True
162
- self .crc_worker .start ()
163
159
self .output_worker .start ()
164
160
for worker in self .compression_workers :
165
161
worker .start ()
166
162
167
163
def stop_immediately (self ):
168
164
"""Stop, but do not care for remaining work"""
169
165
self .running = False
170
- self .crc_worker .join ()
171
166
self .output_worker .join ()
172
167
for worker in self .compression_workers :
173
168
worker .join ()
@@ -181,7 +176,6 @@ def write(self, b) -> int:
181
176
self .previous_block = data
182
177
self .index += 1
183
178
worker_index = index % self .threads
184
- self .crc_queue .put (data )
185
179
self .input_queues [worker_index ].put ((data , zdict ))
186
180
return len (data )
187
181
@@ -198,7 +192,6 @@ def flush(self):
198
192
199
193
def close (self ) -> None :
200
194
self .flush ()
201
- self .crc_queue .join ()
202
195
self .stop_immediately ()
203
196
# Write an empty deflate block with a lost block marker.
204
197
self .raw .write (isal_zlib .compress (b"" , wbits = - 15 ))
@@ -212,20 +205,6 @@ def close(self) -> None:
212
205
def closed (self ) -> bool :
213
206
return self ._closed
214
207
215
- def _calculate_crc (self ):
216
- crc = isal_zlib .crc32 (b"" )
217
- size = 0
218
- while self .running :
219
- try :
220
- data = self .crc_queue .get (timeout = 0.05 )
221
- except queue .Empty :
222
- continue
223
- crc = isal_zlib .crc32 (data , crc )
224
- size += len (data )
225
- self .crc_queue .task_done ()
226
- self ._crc = crc
227
- self ._size = size
228
-
229
208
def _compress (self , index : int ):
230
209
in_queue = self .input_queues [index ]
231
210
out_queue = self .output_queues [index ]
@@ -238,23 +217,31 @@ def _compress(self, index: int):
238
217
self .level , wbits = - 15 , zdict = zdict )
239
218
compressed = compressor .compress (data ) + compressor .flush (
240
219
isal_zlib .Z_SYNC_FLUSH )
241
- out_queue .put (compressed )
220
+ crc = isal_zlib .crc32 (data )
221
+ data_length = len (data )
222
+ out_queue .put ((compressed , crc , data_length ))
242
223
in_queue .task_done ()
243
224
244
225
def _write (self ):
245
226
index = 0
246
227
output_queues = self .output_queues
247
228
fp = self .raw
229
+ total_crc = 0
230
+ size = 0
248
231
while self .running :
249
232
out_index = index % self .threads
250
233
output_queue = output_queues [out_index ]
251
234
try :
252
- data = output_queue .get (timeout = 0.05 )
235
+ compressed , crc , data_length = output_queue .get (timeout = 0.05 )
253
236
except queue .Empty :
254
237
continue
255
- fp .write (data )
238
+ total_crc = isal_zlib .crc32_combine (total_crc , crc , data_length )
239
+ size += data_length
240
+ fp .write (compressed )
256
241
output_queue .task_done ()
257
242
index += 1
243
+ self ._crc = total_crc
244
+ self ._size = size
258
245
259
246
def writable (self ) -> bool :
260
247
return True
0 commit comments