@@ -1899,24 +1899,21 @@ static char *cram_compress_by_method(cram_slice *s, char *in, size_t in_size,
1899
1899
return NULL ;
1900
1900
}
1901
1901
1902
-
1903
1902
/*
1904
- * Compresses a block using one of two different zlib strategies. If we only
1905
- * want one choice set strat2 to be -1.
1906
- *
1907
- * The logic here is that sometimes Z_RLE does a better job than Z_FILTERED
1908
- * or Z_DEFAULT_STRATEGY on quality data. If so, we'd rather use it as it is
1909
- * significantly faster.
1910
- *
1911
- * Method and level -1 implies defaults, as specified in cram_fd.
1903
+ * A copy of cram_compress_block2 with added recursion detection.
1904
+ * This is only called for error handling where the auto-tuning has failed.
1905
+ * The simplest way of doing this is recusion + an additional argument, but
1906
+ * we didn't want to complicate the existing code hence this is static.
1912
1907
*/
1913
- int cram_compress_block2 (cram_fd * fd , cram_slice * s ,
1914
- cram_block * b , cram_metrics * metrics ,
1915
- int method , int level ) {
1908
+ static int cram_compress_block3 (cram_fd * fd , cram_slice * s ,
1909
+ cram_block * b , cram_metrics * metrics ,
1910
+ int method , int level ,
1911
+ int recurse ) {
1916
1912
1917
1913
if (!b )
1918
1914
return 0 ;
1919
1915
1916
+ int orig_method = method ;
1920
1917
char * comp = NULL ;
1921
1918
size_t comp_size = 0 ;
1922
1919
int strat ;
@@ -2249,8 +2246,23 @@ int cram_compress_block2(cram_fd *fd, cram_slice *s,
2249
2246
b -> content_id , & comp_size , method ,
2250
2247
method == GZIP_1 ? 1 : level ,
2251
2248
strat );
2252
- if (!comp )
2249
+ if (!comp ) {
2250
+ // Our cached best method failed, but maybe another works?
2251
+ // Rerun with trial mode engaged again.
2252
+ if (!recurse ) {
2253
+ hts_log_warning ("Compressed block ID %d method %s failed, "
2254
+ "redoing trial" , b -> content_id ,
2255
+ cram_block_method2str (method ));
2256
+ pthread_mutex_lock (& fd -> metrics_lock );
2257
+ metrics -> trial = NTRIALS ;
2258
+ metrics -> next_trial = TRIAL_SPAN ;
2259
+ metrics -> revised_method = orig_method ;
2260
+ pthread_mutex_unlock (& fd -> metrics_lock );
2261
+ return cram_compress_block3 (fd , s , b , metrics , method ,
2262
+ level , 1 );
2263
+ }
2253
2264
return -1 ;
2265
+ }
2254
2266
2255
2267
if (comp_size < b -> uncomp_size ) {
2256
2268
free (b -> data );
@@ -2290,6 +2302,19 @@ int cram_compress_block2(cram_fd *fd, cram_slice *s,
2290
2302
2291
2303
return 0 ;
2292
2304
}
2305
+
2306
+ /*
2307
+ * Compresses a block using a selection of compression codecs and options.
2308
+ * The best is learnt and used for subsequent slices, periodically resampling.
2309
+ *
2310
+ * Method and level -1 implies defaults, as specified in cram_fd.
2311
+ */
2312
+ int cram_compress_block2 (cram_fd * fd , cram_slice * s ,
2313
+ cram_block * b , cram_metrics * metrics ,
2314
+ int method , int level ) {
2315
+ return cram_compress_block3 (fd , s , b , metrics , method , level , 0 );
2316
+ }
2317
+
2293
2318
int cram_compress_block (cram_fd * fd , cram_block * b , cram_metrics * metrics ,
2294
2319
int method , int level ) {
2295
2320
return cram_compress_block2 (fd , NULL , b , metrics , method , level );
0 commit comments