/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by The HDF Group.                                               *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
 * terms governing use, modification, and redistribution, is contained in    *
 * the LICENSE file, which can be found at the root of the source code       *
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
 * If you do not have access to either file, you may request a copy from     *
 * help@hdfgroup.org.                                                        *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#if !(defined H5F_FRIEND || defined H5F_MODULE)
#error "Do not include this file outside the H5F package!"
#endif

#ifndef H5Fpkg_H
#define H5Fpkg_H

#include "H5Fprivate.h"

#include "H5private.h"   
#include "H5ACprivate.h" 
#include "H5Bprivate.h"  
#include "H5FDprivate.h" 
#include "H5FLprivate.h" 
#include "H5FOprivate.h" 
#include "H5FSprivate.h" 
#include "H5Gprivate.h"  
#include "H5Oprivate.h"  
#include "H5PBprivate.h" 
#include "H5UCprivate.h" 

#ifdef NDEBUG
#undef H5F_DEBUG
#endif

#define H5F_SUPER_WRITE_ACCESS      0x01
#define H5F_SUPER_FILE_OK           0x02
#define H5F_SUPER_SWMR_WRITE_ACCESS 0x04
#define H5F_SUPER_ALL_FLAGS         (H5F_SUPER_WRITE_ACCESS | H5F_SUPER_FILE_OK | H5F_SUPER_SWMR_WRITE_ACCESS)

#define H5F_ACC_PUBLIC_FLAGS 0x007fu

#define H5F_FS_MERGE_METADATA 0x01 
#define H5F_FS_MERGE_RAWDATA  0x02 

#define H5F_HAVE_FREE_SPACE_MANAGER(F)                                                                       \
    ((F)->shared->fs_strategy == H5F_FSPACE_STRATEGY_FSM_AGGR ||                                             \
     (F)->shared->fs_strategy == H5F_FSPACE_STRATEGY_PAGE)

#define H5F_MAX_DRVINFOBLOCK_SIZE 1024 
#define H5F_DRVINFOBLOCK_HDR_SIZE 16   

#define H5F_SIZEOF_CHKSUM 4 

#define H5F_SUPERBLOCK_FIXED_SIZE (H5F_SIGNATURE_LEN + 1) 

#define H5F_SUPERBLOCK_MINIMAL_VARLEN_SIZE 7

#define H5F_SUPERBLOCK_VARLEN_SIZE_COMMON                                                                    \
    (2                                                               \
     + 1                                                                                       \
     + 3                                           \
     + 1                                                                                       \
     + 4                                                                 \
     + 4) 
#define H5F_SUPERBLOCK_VARLEN_SIZE_V0(sizeof_addr, sizeof_size)                                              \
    (H5F_SUPERBLOCK_VARLEN_SIZE_COMMON                                      \
     + (sizeof_addr)                                                                       \
     + (sizeof_addr)                                                                           \
     + (sizeof_addr)                                                                        \
     + (sizeof_addr)                                                               \
     + H5G_SIZEOF_ENTRY(sizeof_addr, sizeof_size)) 
#define H5F_SUPERBLOCK_VARLEN_SIZE_V1(sizeof_addr, sizeof_size)                                              \
    (H5F_SUPERBLOCK_VARLEN_SIZE_COMMON                                      \
     + 2                                                                      \
     + 2                                                                                       \
     + (sizeof_addr)                                                                       \
     + (sizeof_addr)                                                                           \
     + (sizeof_addr)                                                                        \
     + (sizeof_addr)                                                               \
     + H5G_SIZEOF_ENTRY(sizeof_addr, sizeof_size)) 
#define H5F_SUPERBLOCK_VARLEN_SIZE_V2(sizeof_addr)                                                           \
    (2                                                                 \
     + 1                                                                              \
     + (sizeof_addr)                                                                       \
     + (sizeof_addr)                                                       \
     + (sizeof_addr)                                                                        \
     + (sizeof_addr)                                                   \
     + H5F_SIZEOF_CHKSUM) 
#define H5F_SUPERBLOCK_VARLEN_SIZE(v, sizeof_addr, sizeof_size)                                              \
    ((v == 0 ? H5F_SUPERBLOCK_VARLEN_SIZE_V0(sizeof_addr, sizeof_size) : 0) +                                \
     (v == 1 ? H5F_SUPERBLOCK_VARLEN_SIZE_V1(sizeof_addr, sizeof_size) : 0) +                                \
     (v >= 2 ? H5F_SUPERBLOCK_VARLEN_SIZE_V2(sizeof_addr) : 0))

#define H5F_SUPERBLOCK_SIZE(s)                                                                               \
    (H5F_SUPERBLOCK_FIXED_SIZE +                                                                             \
     H5F_SUPERBLOCK_VARLEN_SIZE((s)->super_vers, (s)->sizeof_addr, (s)->sizeof_size))

#define H5F_SUPERBLOCK_SPEC_READ_SIZE (H5F_SUPERBLOCK_FIXED_SIZE + H5F_SUPERBLOCK_VARLEN_SIZE(2, 8, 8))

#define H5F_SUPER_STATUS_OFF_V01                                                                             \
    (unsigned)(2                                                     \
               + 1                                                                             \
               + 3                                 \
               + 1                                                                             \
               + 4) 

#define H5F_SUPER_STATUS_OFF(v) (v >= 2 ? (unsigned)2 : H5F_SUPER_STATUS_OFF_V01)

#define H5F_SUPER_STATUS_FLAGS_OFF(v) (H5F_SUPERBLOCK_FIXED_SIZE + H5F_SUPER_STATUS_OFF(v))

#define H5F_SUPER_STATUS_FLAGS_SIZE(v) (v >= 2 ? 1 : 4)

typedef struct H5F_efc_t H5F_efc_t;

typedef struct H5F_superblock_cache_ud_t {
    
    H5F_t *f;                           
    bool   ignore_drvrinfo;             
                                        
    unsigned sym_leaf_k;                
    unsigned btree_k[H5B_NUM_BTREE_ID]; 
    haddr_t  stored_eof;                
    bool     drvrinfo_removed;          
    unsigned super_vers;                
} H5F_superblock_cache_ud_t;

typedef struct H5F_drvrinfo_cache_ud_t {
    H5F_t  *f;           
    haddr_t driver_addr; 
} H5F_drvrinfo_cache_ud_t;

struct H5F_blk_aggr_t {
    unsigned long feature_flag; 
    hsize_t       alloc_size;   
    hsize_t       tot_size;     
    hsize_t       size;         
    haddr_t       addr;         
};

typedef struct H5F_meta_accum_t {
    unsigned char *buf;        
    haddr_t        loc;        
    size_t         size;       
    size_t         alloc_size; 
    size_t         dirty_off;  
    size_t         dirty_len;  
    bool           dirty;      
} H5F_meta_accum_t;

typedef struct H5F_mount_t {
    struct H5G_t *group; 
    struct H5F_t *file;  
} H5F_mount_t;

typedef struct H5F_mtab_t {
    unsigned     nmounts; 
    unsigned     nalloc;  
    H5F_mount_t *child;   
} H5F_mtab_t;

typedef struct H5F_super_t {
    H5AC_info_t cache_info;                
    unsigned    super_vers;                
    uint8_t     sizeof_addr;               
    uint8_t     sizeof_size;               
    uint8_t     status_flags;              
    unsigned    sym_leaf_k;                
    unsigned    btree_k[H5B_NUM_BTREE_ID]; 
    haddr_t     base_addr;                 
                                           
    haddr_t      ext_addr;                 
    haddr_t      driver_addr;              
    haddr_t      root_addr;                
    H5G_entry_t *root_ent;                 
} H5F_super_t;

struct H5F_shared_t {
    H5FD_t        *lf;          
    H5F_super_t   *sblock;      
    H5O_drvinfo_t *drvinfo;     
    bool drvinfo_sb_msg_exists; 
    unsigned   nrefs;           
    unsigned   flags;           
    H5F_mtab_t mtab;            
    H5F_efc_t *efc;             

    
    uint8_t       sizeof_addr;   
    uint8_t       sizeof_size;   
    haddr_t       sohm_addr;     
    unsigned      sohm_vers;     
    unsigned      sohm_nindexes; 
    unsigned long feature_flags; 
    haddr_t       maxaddr;       

    H5PB_t             *page_buf;                    
    H5AC_t             *cache;                       
    H5AC_cache_config_t mdc_initCacheCfg;            
                                                     
                                                     
                                                     
    H5AC_cache_image_config_t mdc_initCacheImageCfg; 
                                                     
                                                     
                                                     
                                                     
    bool use_mdc_logging;                            
    bool start_mdc_log_on_access;                    
                                                     
    char              *mdc_log_location;             
    hid_t              fcpl_id;                      
    H5F_close_degree_t fc_degree;                    
    bool     evict_on_close; 
    size_t   rdcc_nslots;    
    size_t   rdcc_nbytes;    
    double   rdcc_w0;        
    size_t   sieve_buf_size; 
    hsize_t  threshold;      
    hsize_t  alignment;      
    unsigned gc_ref;         
    H5F_libver_t         low_bound;             
    H5F_libver_t         high_bound;            
    bool                 store_msg_crt_idx;     
    unsigned             ncwfs;                 
    struct H5HG_heap_t **cwfs;                  
    struct H5G_t        *root_grp;              
    H5FO_t              *open_objs;             
    H5UC_t              *grp_btree_shared;      
    bool                 use_file_locking;      
    bool                 ignore_disabled_locks; 
    bool                 closing;               
    uint64_t             rfic_flags;            

    
    H5VL_connector_t *vol_conn; 
    void             *vol_info; 

    
    H5F_fspace_strategy_t fs_strategy;  
    hsize_t               fs_threshold; 
    bool                  fs_persist;   
    unsigned              fs_version;   
                                        
    bool    use_tmp_space;              
    haddr_t tmp_addr;                   
    bool    point_of_no_return; 

    H5F_fs_state_t fs_state[H5F_MEM_PAGE_NTYPES]; 
    haddr_t        fs_addr[H5F_MEM_PAGE_NTYPES];  
    H5FS_t        *fs_man[H5F_MEM_PAGE_NTYPES];   
    bool           null_fsm_addr;                 
                                                  
    haddr_t eoa_fsm_fsalloc;                      
                                                  
    haddr_t eoa_post_mdci_fsalloc;                
                                                  
                                                  

    
    unsigned   fs_aggr_merge[H5FD_MEM_NTYPES]; 
    H5FD_mem_t fs_type_map[H5FD_MEM_NTYPES];   
    H5F_blk_aggr_t meta_aggr;  
    H5F_blk_aggr_t sdata_aggr; 

    
    hsize_t fs_page_size;     
    size_t  pgend_meta_thres; 

    
    H5F_meta_accum_t accum; 

    
    unsigned  read_attempts;        
    unsigned  retries_nbins;        
    uint32_t *retries[H5AC_NTYPES]; 

    
    H5F_object_flush_t object_flush;           
    bool               crt_dset_min_ohdr_flag; 

    char *extpath; 

#ifdef H5_HAVE_PARALLEL
    H5P_coll_md_read_flag_t coll_md_read;  
    bool                    coll_md_write; 
#endif                                     
};

struct H5F_t {
    char          *open_name;   
    char          *actual_name; 
    H5F_shared_t  *shared;      
    H5VL_object_t *vol_obj;     
    unsigned       nopen_objs;  
    H5FO_t        *obj_count;   
    bool           id_exists;   
    bool           closing;     
    struct H5F_t  *parent;      
    unsigned       nmounts;     
};

H5FL_EXTERN(H5F_t);

H5FL_EXTERN(H5F_shared_t);

H5_DLLVAR htri_t use_locks_env_g;
H5_DLLVAR htri_t ignore_disabled_locks_g;

H5_DLL herr_t H5F__post_open(H5F_t *f);
H5_DLL H5F_t *H5F__reopen(H5F_t *f);
H5_DLL herr_t H5F__flush(H5F_t *f);
H5_DLL herr_t H5F__is_hdf5(const char *name, hid_t fapl_id, bool *is_hdf5);
H5_DLL herr_t H5F__get_file_image(H5F_t *f, void *buf_ptr, size_t buf_len, size_t *image_len);
H5_DLL herr_t H5F__get_info(H5F_t *f, H5F_info2_t *finfo);
H5_DLL herr_t H5F__format_convert(H5F_t *f);
H5_DLL herr_t H5F__start_swmr_write(H5F_t *f);
H5_DLL herr_t H5F__close(H5F_t *f);
H5_DLL herr_t H5F__set_libver_bounds(H5F_t *f, H5F_libver_t low, H5F_libver_t high);
H5_DLL herr_t H5F__get_cont_info(const H5F_t *f, H5VL_file_cont_info_t *info);
H5_DLL herr_t H5F__parse_file_lock_env_var(htri_t *use_locks, htri_t *ignore_disabled_locks);
H5_DLL herr_t H5F__delete(const char *filename, hid_t fapl_id);

H5_DLL herr_t H5F__close_mounts(H5F_t *f);
H5_DLL herr_t H5F__mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs);

H5_DLL herr_t H5F__super_init(H5F_t *f);
H5_DLL herr_t H5F__super_read(H5F_t *f, H5P_genplist_t *fa_plist, bool initial_read);
H5_DLL herr_t H5F__super_size(H5F_t *f, hsize_t *super_size, hsize_t *super_ext_size);
H5_DLL herr_t H5F__super_free(H5F_super_t *sblock);

H5_DLL herr_t H5F__super_ext_open(H5F_t *f, haddr_t ext_addr, H5O_loc_t *ext_ptr);
H5_DLL herr_t H5F__super_ext_write_msg(H5F_t *f, unsigned id, void *mesg, bool may_create,
                                       unsigned mesg_flags);
H5_DLL herr_t H5F__super_ext_remove_msg(H5F_t *f, unsigned id);
H5_DLL herr_t H5F__super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr, bool was_created);

H5_DLL herr_t H5F__accum_read(H5F_shared_t *f_sh, H5FD_mem_t type, haddr_t addr, size_t size, void *buf);
H5_DLL herr_t H5F__accum_write(H5F_shared_t *f_sh, H5FD_mem_t type, haddr_t addr, size_t size,
                               const void *buf);
H5_DLL herr_t H5F__accum_free(H5F_shared_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size);
H5_DLL herr_t H5F__accum_flush(H5F_shared_t *f_sh);
H5_DLL herr_t H5F__accum_reset(H5F_shared_t *f_sh, bool flush, bool force);

H5_DLL herr_t        H5F__sfile_add(H5F_shared_t *shared);
H5_DLL H5F_shared_t *H5F__sfile_search(H5FD_t *lf);
H5_DLL herr_t        H5F__sfile_remove(H5F_shared_t *shared);

#ifdef H5_HAVE_PARALLEL
H5_DLL herr_t H5F__get_mpi_atomicity(const H5F_t *file, bool *flag);
H5_DLL herr_t H5F__set_mpi_atomicity(H5F_t *file, bool flag);
#endif 

H5_DLL H5F_efc_t *H5F__efc_create(unsigned max_nfiles);
H5_DLL herr_t     H5F__efc_open(bool try, H5F_efc_t *efc, H5F_t **file, const char *name, unsigned flags,
                                hid_t fcpl_id, hid_t fapl_id);
H5_DLL unsigned   H5F__efc_max_nfiles(H5F_efc_t *efc);
H5_DLL herr_t     H5F__efc_release(H5F_efc_t *efc);
H5_DLL herr_t     H5F__efc_destroy(H5F_efc_t *efc);
H5_DLL herr_t     H5F__efc_try_close(H5F_t *f);

H5_DLL haddr_t H5F__alloc(H5F_t *f, H5F_mem_t type, hsize_t size, haddr_t *frag_addr, hsize_t *frag_size);
H5_DLL herr_t  H5F__free(H5F_t *f, H5F_mem_t type, haddr_t addr, hsize_t size);
H5_DLL htri_t  H5F__try_extend(H5F_t *f, H5FD_mem_t type, haddr_t blk_end, hsize_t extra_requested);

H5_DLL herr_t H5F__set_eoa(const H5F_t *f, H5F_mem_t type, haddr_t addr);
H5_DLL herr_t H5F__set_base_addr(const H5F_t *f, haddr_t addr);
H5_DLL herr_t H5F__set_paged_aggr(const H5F_t *f, bool paged);
H5_DLL herr_t H5F__get_max_eof_eoa(const H5F_t *f, haddr_t *max_eof_eoa);

H5_DLL herr_t H5F__evict_cache_entries(H5F_t *f);

#ifdef H5F_TESTING
H5_DLL herr_t H5F__get_sohm_mesg_count_test(hid_t fid, unsigned type_id, size_t *mesg_count);
H5_DLL herr_t H5F__check_cached_stab_test(hid_t file_id);
H5_DLL herr_t H5F__get_maxaddr_test(hid_t file_id, haddr_t *maxaddr);
H5_DLL herr_t H5F__get_sbe_addr_test(hid_t file_id, haddr_t *sbe_addr);
H5_DLL htri_t H5F__same_file_test(hid_t file_id1, hid_t file_id2);
H5_DLL herr_t H5F__reparse_file_lock_variable_test(void);
#endif 

#endif 
