4848#include "htslib/hts_endian.h"
4949#include "cram/pooled_alloc.h"
5050#include "hts_internal.h"
51+ #include "bgzf_internal.h"
52+ #include "htslib/khash.h"
5153
5254#ifndef EFTYPE
5355#define EFTYPE ENOEXEC
5456#endif
5557
56- #define BGZF_CACHE
5758#define BGZF_MT
5859
5960#define BLOCK_HEADER_LENGTH 18
7677*/
7778static const uint8_t g_magic [19 ] = "\037\213\010\4\0\0\0\0\0\377\6\0\102\103\2\0\0\0" ;
7879
79- #ifdef BGZF_CACHE
8080typedef struct {
8181 int size ;
8282 uint8_t * block ;
8383 int64_t end_offset ;
8484} cache_t ;
8585
86- #include "htslib/khash.h"
87- KHASH_MAP_INIT_INT64 (cache , cache_t )
88- #endif
86+ KHASH_MAP_INIT_INT64 (bgzf_cache , cache_t )
8987
90- struct bgzf_cache_t {
91- khash_t (cache ) * h ;
92- khint_t last_pos ;
93- };
88+ // struct bgzf_cache_t is defined in bgzf_internal.h
9489
9590#ifdef BGZF_MT
9691
@@ -409,20 +404,21 @@ static BGZF *bgzf_read_init(hFILE *hfpr, const char *filename)
409404 errno = EFTYPE ;
410405 return NULL ;
411406 }
412- #ifdef BGZF_CACHE
407+
413408 if (!(fp -> cache = malloc (sizeof (* fp -> cache )))) {
414409 free (fp -> uncompressed_block );
415410 free (fp );
416411 return NULL ;
417412 }
418- if (!(fp -> cache -> h = kh_init (cache ))) {
413+ if (!(fp -> cache -> h = kh_init (bgzf_cache ))) {
419414 free (fp -> uncompressed_block );
420415 free (fp -> cache );
421416 free (fp );
422417 return NULL ;
423418 }
424419 fp -> cache -> last_pos = 0 ;
425- #endif
420+ fp -> cache -> private_data = NULL ;
421+ fp -> cache -> private_data_cleanup = (bgzf_private_data_cleanup_func * ) NULL ;
426422 return fp ;
427423}
428424
@@ -442,6 +438,15 @@ static BGZF *bgzf_write_init(const char *mode)
442438 fp = (BGZF * )calloc (1 , sizeof (BGZF ));
443439 if (fp == NULL ) goto mem_fail ;
444440 fp -> is_write = 1 ;
441+
442+ fp -> cache = malloc (sizeof (bgzf_cache_t ));
443+ if (!fp -> cache )
444+ goto mem_fail ;
445+ fp -> cache -> h = NULL ;
446+ fp -> cache -> last_pos = 0 ;
447+ fp -> cache -> private_data = NULL ;
448+ fp -> cache -> private_data_cleanup = (bgzf_private_data_cleanup_func * ) NULL ;
449+
445450 int compress_level = mode2level (mode );
446451 if ( compress_level == -2 )
447452 {
@@ -479,6 +484,7 @@ static BGZF *bgzf_write_init(const char *mode)
479484
480485fail :
481486 if (fp != NULL ) {
487+ free (fp -> cache );
482488 free (fp -> uncompressed_block );
483489 free (fp -> gz_stream );
484490 free (fp );
@@ -896,15 +902,16 @@ static int check_header(const uint8_t *header)
896902 && unpackInt16 ((uint8_t * )& header [14 ]) == 2 ) ? 0 : -1 ;
897903}
898904
899- #ifdef BGZF_CACHE
900905static void free_cache (BGZF * fp )
901906{
902907 khint_t k ;
903- if (fp -> is_write ) return ;
904- khash_t (cache ) * h = fp -> cache -> h ;
905- for (k = kh_begin (h ); k < kh_end (h ); ++ k )
906- if (kh_exist (h , k )) free (kh_val (h , k ).block );
907- kh_destroy (cache , h );
908+ if (fp -> cache -> h ) {
909+ khash_t (bgzf_cache ) * h = fp -> cache -> h ;
910+ for (k = kh_begin (h ); k < kh_end (h ); ++ k )
911+ if (kh_exist (h , k )) free (kh_val (h , k ).block );
912+ kh_destroy (bgzf_cache , h );
913+ }
914+ bgzf_clear_private_data (fp );
908915 free (fp -> cache );
909916}
910917
@@ -913,8 +920,8 @@ static int load_block_from_cache(BGZF *fp, int64_t block_address)
913920 khint_t k ;
914921 cache_t * p ;
915922
916- khash_t (cache ) * h = fp -> cache -> h ;
917- k = kh_get (cache , h , block_address );
923+ khash_t (bgzf_cache ) * h = fp -> cache -> h ;
924+ k = kh_get (bgzf_cache , h , block_address );
918925 if (k == kh_end (h )) return 0 ;
919926 p = & kh_val (h , k );
920927 if (fp -> block_length != 0 ) fp -> block_offset = 0 ;
@@ -937,7 +944,7 @@ static void cache_block(BGZF *fp, int size)
937944 uint8_t * block = NULL ;
938945 cache_t * p ;
939946 //fprintf(stderr, "Cache block at %llx\n", (int)fp->block_address);
940- khash_t (cache ) * h = fp -> cache -> h ;
947+ khash_t (bgzf_cache ) * h = fp -> cache -> h ;
941948 if (BGZF_MAX_BLOCK_SIZE >= fp -> cache_size ) return ;
942949 if (fp -> block_length < 0 || fp -> block_length > BGZF_MAX_BLOCK_SIZE ) return ;
943950 if ((kh_size (h ) + 1 ) * BGZF_MAX_BLOCK_SIZE > (uint32_t )fp -> cache_size ) {
@@ -959,13 +966,13 @@ static void cache_block(BGZF *fp, int size)
959966
960967 if (k != k_orig ) {
961968 block = kh_val (h , k ).block ;
962- kh_del (cache , h , k );
969+ kh_del (bgzf_cache , h , k );
963970 }
964971 } else {
965972 block = (uint8_t * )malloc (BGZF_MAX_BLOCK_SIZE );
966973 }
967974 if (!block ) return ;
968- k = kh_put (cache , h , fp -> block_address , & ret );
975+ k = kh_put (bgzf_cache , h , fp -> block_address , & ret );
969976 if (ret <= 0 ) { // kh_put failed, or in there already (shouldn't happen)
970977 free (block );
971978 return ;
@@ -976,11 +983,6 @@ static void cache_block(BGZF *fp, int size)
976983 p -> block = block ;
977984 memcpy (p -> block , fp -> uncompressed_block , p -> size );
978985}
979- #else
980- static void free_cache (BGZF * fp ) {}
981- static int load_block_from_cache (BGZF * fp , int64_t block_address ) {return 0 ;}
982- static void cache_block (BGZF * fp , int size ) {}
983- #endif
984986
985987/*
986988 * Absolute htell in this compressed file.
0 commit comments