/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * 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 H5D_FRIEND || defined H5D_MODULE)
#error "Do not include this file outside the H5D package!"
#endif

#ifndef H5Dpkg_H
#define H5Dpkg_H

#include "H5Dprivate.h"

#include "H5ACprivate.h" 
#include "H5B2private.h" 
#include "H5Fprivate.h"  
#include "H5FLprivate.h" 
#include "H5Gprivate.h"  
#include "H5SLprivate.h" 
#include "H5Tprivate.h"  

#define H5D_MINHDR_SIZE 256

#define H5D_MARK_SPACE  0x01
#define H5D_MARK_LAYOUT 0x02

#define H5D_FARRAY_CREATE_PARAM_SIZE         1  
#define H5D_FARRAY_MAX_DBLK_PAGE_NELMTS_BITS 10 

#define H5D_EARRAY_CREATE_PARAM_SIZE           5  
#define H5D_EARRAY_MAX_NELMTS_BITS             32 
#define H5D_EARRAY_IDX_BLK_ELMTS               4
#define H5D_EARRAY_SUP_BLK_MIN_DATA_PTRS       4
#define H5D_EARRAY_DATA_BLK_MIN_ELMTS          16
#define H5D_EARRAY_MAX_DBLOCK_PAGE_NELMTS_BITS 10 

#define H5D_BT2_CREATE_PARAM_SIZE 6 
#define H5D_BT2_NODE_SIZE         2048
#define H5D_BT2_SPLIT_PERC        100
#define H5D_BT2_MERGE_PERC        40

#define H5D_LAYOUT_CB_PERFORM_IO(IO_INFO)                                                                    \
    (((IO_INFO)->use_select_io == H5D_SELECTION_IO_MODE_OFF) ||                                              \
     ((IO_INFO)->count == 1 && (IO_INFO)->max_tconv_type_size == 0))

#define H5D_INIT_PIECE_TCONV(IO_INFO, DINFO, PIECE_INFO)                                                     \
    {                                                                                                        \
                                                                \
        if ((IO_INFO)->may_use_in_place_tconv) {                                                             \
            size_t mem_type_size  = ((IO_INFO)->op_type == H5D_IO_OP_READ)                                   \
                                        ? (DINFO)->type_info.dst_type_size                                   \
                                        : (DINFO)->type_info.src_type_size;                                  \
            size_t file_type_size = ((IO_INFO)->op_type == H5D_IO_OP_READ)                                   \
                                        ? (DINFO)->type_info.src_type_size                                   \
                                        : (DINFO)->type_info.dst_type_size;                                  \
                                                                                                             \
                                             \
            if (mem_type_size >= file_type_size) {                                                           \
                bool    is_contig;                                                                           \
                hsize_t sel_off;                                                                             \
                                                                                                             \
                                                                       \
                if (H5S_select_contig_block((PIECE_INFO)->mspace, &is_contig, &sel_off, NULL) < 0)           \
                    HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't check if dataspace is contiguous");  \
                                                                                                             \
                                                                                                          \
                if (is_contig) {                                                                             \
                    H5_CHECK_OVERFLOW(sel_off, hsize_t, size_t);                                             \
                    (PIECE_INFO)->in_place_tconv = true;                                                     \
                    (PIECE_INFO)->buf_off        = (size_t)sel_off * mem_type_size;                          \
                }                                                                                            \
            }                                                                                                \
        }                                                                                                    \
                                                                                                             \
                               \
        if (!(PIECE_INFO)->in_place_tconv) {                                                                 \
            hsize_t tconv_buf_hsize;                                                                         \
            hsize_t old_size;                                                                                \
            H5_CHECKED_ASSIGN(tconv_buf_hsize, hsize_t, (IO_INFO)->tconv_buf_size, size_t);                  \
            old_size = tconv_buf_hsize;                                                                      \
            tconv_buf_hsize += (PIECE_INFO)->piece_points *                                                  \
                               MAX((DINFO)->type_info.src_type_size, (DINFO)->type_info.dst_type_size);      \
            if (H5_UNLIKELY(tconv_buf_hsize < old_size || tconv_buf_hsize > SIZE_MAX))                       \
                (IO_INFO)->tconv_buf_overflow = true;                                                        \
            else                                                                                             \
                (IO_INFO)->tconv_buf_size = (size_t)tconv_buf_hsize;                                         \
        }                                                                                                    \
    }

#define H5D_VIRTUAL_FIND_OR_ADD_NAME(NAME_TYPE, LAYOUT, STR, STRLEN, ENT, ERR)                               \
    do {                                                                                                     \
                                                                         \
        H5O_storage_virtual_ent_t *_tmp_ent = NULL;                         \
                                                                                                             \
        if ((ENT) > (LAYOUT)->storage.u.virt.list)                                                           \
            HASH_FIND(hh_source_##NAME_TYPE, (LAYOUT)->storage.u.virt.source_##NAME_TYPE##_hash_table, STR,  \
                      STRLEN, _tmp_ent);                                                                     \
        if (_tmp_ent) {                                                                                      \
                          \
            assert(_tmp_ent >= (LAYOUT)->storage.u.virt.list && _tmp_ent < (ENT));                           \
            (ENT)->source_##NAME_TYPE##_orig = (size_t)(_tmp_ent - (LAYOUT)->storage.u.virt.list);           \
            (ENT)->source_##NAME_TYPE##_name = _tmp_ent->source_##NAME_TYPE##_name;                          \
        }                                                                                                    \
        else {                                                                                               \
                            \
            if (NULL == ((ENT)->source_##NAME_TYPE##_name = (char *)H5MM_malloc((STRLEN) + 1)))              \
                HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, ERR, "unable to allocate memory for source name");   \
            (ENT)->source_##NAME_TYPE##_orig = SIZE_MAX;                                                     \
            H5MM_memcpy((ENT)->source_##NAME_TYPE##_name, STR, (STRLEN) + 1);                                \
                                                                                                             \
                                                                                                  \
            HASH_ADD_KEYPTR(hh_source_##NAME_TYPE, (LAYOUT)->storage.u.virt.source_##NAME_TYPE##_hash_table, \
                            (ENT)->source_##NAME_TYPE##_name, STRLEN, ENT);                                  \
        }                                                                                                    \
    } while (0)

typedef struct H5D_type_info_t {
    
    const H5T_t *mem_type;  
    const H5T_t *dset_type; 
    const H5T_t *src_type;  
    const H5T_t *dst_type;  
    H5T_path_t  *tpath;     

    
    size_t                   src_type_size;  
    size_t                   dst_type_size;  
    bool                     is_conv_noop;   
    bool                     is_xform_noop;  
    const H5T_subset_info_t *cmpd_subset;    
    H5T_bkg_t                need_bkg;       
    size_t                   request_nelmts; 
} H5D_type_info_t;

struct H5D_io_info_t;
struct H5D_dset_io_info_t;
typedef struct H5D_shared_t H5D_shared_t;

typedef herr_t (*H5D_layout_construct_func_t)(H5F_t *f, H5D_t *dset);
typedef herr_t (*H5D_layout_init_func_t)(H5F_t *f, H5D_t *dset, hid_t dapl_id, bool open_op);
typedef bool (*H5D_layout_is_space_alloc_func_t)(const H5O_storage_t *storage);
typedef bool (*H5D_layout_is_data_cached_func_t)(const H5D_shared_t *shared_dset);
typedef herr_t (*H5D_layout_io_init_func_t)(struct H5D_io_info_t *io_info, struct H5D_dset_io_info_t *dinfo);
typedef herr_t (*H5D_layout_mdio_init_func_t)(struct H5D_io_info_t      *io_info,
                                              struct H5D_dset_io_info_t *dinfo);
typedef herr_t (*H5D_layout_read_func_t)(struct H5D_io_info_t *io_info, struct H5D_dset_io_info_t *dinfo);
typedef herr_t (*H5D_layout_write_func_t)(struct H5D_io_info_t *io_info, struct H5D_dset_io_info_t *dinfo);
typedef herr_t (*H5D_layout_read_md_func_t)(struct H5D_io_info_t *io_info);
typedef herr_t (*H5D_layout_write_md_func_t)(struct H5D_io_info_t *io_info);
typedef ssize_t (*H5D_layout_readvv_func_t)(const struct H5D_io_info_t      *io_info,
                                            const struct H5D_dset_io_info_t *dset_info, size_t dset_max_nseq,
                                            size_t *dset_curr_seq, size_t dset_len_arr[],
                                            hsize_t dset_offset_arr[], size_t mem_max_nseq,
                                            size_t *mem_curr_seq, size_t mem_len_arr[],
                                            hsize_t mem_offset_arr[]);
typedef ssize_t (*H5D_layout_writevv_func_t)(const struct H5D_io_info_t      *io_info,
                                             const struct H5D_dset_io_info_t *dset_info, size_t dset_max_nseq,
                                             size_t *dset_curr_seq, size_t dset_len_arr[],
                                             hsize_t dset_offset_arr[], size_t mem_max_nseq,
                                             size_t *mem_curr_seq, size_t mem_len_arr[],
                                             hsize_t mem_offset_arr[]);
typedef herr_t (*H5D_layout_flush_func_t)(H5D_t *dataset);
typedef herr_t (*H5D_layout_io_term_func_t)(struct H5D_io_info_t *io_info, struct H5D_dset_io_info_t *di);
typedef herr_t (*H5D_layout_dest_func_t)(H5D_t *dataset);

typedef struct H5D_layout_ops_t {
    H5D_layout_construct_func_t      construct;      
    H5D_layout_init_func_t           init;           
    H5D_layout_is_space_alloc_func_t is_space_alloc; 
    H5D_layout_is_data_cached_func_t
        is_data_cached; 
    H5D_layout_io_init_func_t   io_init;   
    H5D_layout_mdio_init_func_t mdio_init; 
    H5D_layout_read_func_t    ser_read;    
    H5D_layout_write_func_t   ser_write;   
    H5D_layout_readvv_func_t  readvv;      
    H5D_layout_writevv_func_t writevv;     
    H5D_layout_flush_func_t   flush;       
    H5D_layout_io_term_func_t io_term;     
    H5D_layout_dest_func_t    dest;        
} H5D_layout_ops_t;

typedef herr_t (*H5D_io_single_read_func_t)(const struct H5D_io_info_t      *io_info,
                                            const struct H5D_dset_io_info_t *dset_info);
typedef herr_t (*H5D_io_single_write_func_t)(const struct H5D_io_info_t      *io_info,
                                             const struct H5D_dset_io_info_t *dset_info);

typedef herr_t (*H5D_io_single_read_md_func_t)(const struct H5D_io_info_t *io_info, hsize_t nelmts,
                                               H5S_t *file_space, H5S_t *mem_space);
typedef herr_t (*H5D_io_single_write_md_func_t)(const struct H5D_io_info_t *io_info, hsize_t nelmts,
                                                H5S_t *file_space, H5S_t *mem_space);

typedef struct H5D_io_ops_t {
    H5D_layout_read_func_t     multi_read;   
    H5D_layout_write_func_t    multi_write;  
    H5D_io_single_read_func_t  single_read;  
    H5D_io_single_write_func_t single_write; 
} H5D_io_ops_t;

typedef struct H5D_md_io_ops_t {
    H5D_layout_read_md_func_t     multi_read_md;  
    H5D_layout_write_md_func_t    multi_write_md; 
    H5D_io_single_read_md_func_t  single_read_md; 
    H5D_io_single_write_md_func_t single_write_md; 
} H5D_md_io_ops_t;

typedef struct {
    haddr_t dset_addr; 
    hsize_t dset_size; 
} H5D_contig_storage_t;

typedef struct {
    hsize_t *scaled; 
} H5D_chunk_storage_t;

typedef struct {
    void *buf;   
    bool *dirty; 
} H5D_compact_storage_t;

typedef union H5D_storage_t {
    H5D_contig_storage_t  contig;  
    H5D_chunk_storage_t   chunk;   
    H5D_compact_storage_t compact; 
    H5O_efl_t             efl;     
} H5D_storage_t;

typedef enum H5D_io_op_type_t {
    H5D_IO_OP_READ, 
    H5D_IO_OP_WRITE 
} H5D_io_op_type_t;

typedef struct H5D_piece_info_t {
    haddr_t  faddr;                    
    hsize_t  index;                    
    hsize_t  piece_points;             
    hsize_t  scaled[H5O_LAYOUT_NDIMS]; 
    H5S_t   *fspace;                   
    unsigned fspace_shared;  
    H5S_t   *mspace;         
    unsigned mspace_shared;  
    bool     in_place_tconv; 
    size_t   buf_off;        
    bool     filtered_dset;  
    struct H5D_dset_io_info_t *dset_info; 
} H5D_piece_info_t;

typedef struct H5D_dset_io_info_t {
    H5D_t                  *dset;       
    H5D_storage_t          *store;      
    H5D_layout_ops_t        layout_ops; 
    H5_flexible_const_ptr_t buf;        

    H5D_io_ops_t io_ops; 

    H5O_layout_t *layout; 
    hsize_t       nelmts; 

    H5S_t *file_space; 
    H5S_t *mem_space;  

    union {
        struct H5D_chunk_map_t *chunk_map;         
        H5D_piece_info_t       *contig_piece_info; 
    } layout_io_info;

    const H5T_t    *mem_type; 
    H5D_type_info_t type_info;
    bool            skip_io; 
} H5D_dset_io_info_t;

typedef struct H5D_io_info_t {
    
    H5F_shared_t *f_sh; 
#ifdef H5_HAVE_PARALLEL
    MPI_Comm comm;                     
    bool     using_mpi_vfd;            
#endif                                 
    H5D_md_io_ops_t         md_io_ops; 
    H5D_io_op_type_t        op_type;
    size_t                  count;          
    size_t                  filtered_count; 
    H5D_dset_io_info_t     *dsets_info;     
    size_t                  piece_count;    
    size_t                  pieces_added;   
    size_t                  filtered_pieces_added; 
    H5D_piece_info_t      **sel_pieces;            
    H5S_t                 **mem_spaces;            
    H5S_t                 **file_spaces;           
    haddr_t                *addrs;                 
    size_t                 *element_sizes;         
    void                  **rbufs;                 
    const void            **wbufs;                 
    haddr_t                 store_faddr;           
    H5_flexible_const_ptr_t base_maddr;            
    H5D_selection_io_mode_t use_select_io;         
    uint8_t                *tconv_buf;             
    bool                    tconv_buf_allocated;   
    size_t                  tconv_buf_size;        
    uint8_t                *bkg_buf;               
    bool                    bkg_buf_allocated;     
    size_t                  bkg_buf_size;          
    bool                    tconv_buf_overflow;    
    size_t max_tconv_type_size; 
    bool must_fill_bkg; 
    bool may_use_in_place_tconv; 
#ifdef H5_HAVE_PARALLEL
    H5D_mpio_actual_io_mode_t actual_io_mode; 
#endif                                        
    unsigned no_selection_io_cause;           
} H5D_io_info_t;

typedef struct H5D_io_info_wrap_t {
    H5D_io_info_t      *io_info;
    H5D_dset_io_info_t *dinfo;
} H5D_io_info_wrap_t;

typedef struct H5D_chk_idx_info_t {
    H5F_t             *f;      
    const H5O_pline_t *pline;  
    H5O_layout_t      *layout; 
} H5D_chk_idx_info_t;

typedef struct H5D_chunk_rec_t {
    hsize_t  scaled[H5O_LAYOUT_NDIMS]; 
    hsize_t  nbytes;                   
    uint32_t filter_mask;              
    haddr_t  chunk_addr;               
} H5D_chunk_rec_t;

typedef struct H5D_chunk_common_ud_t {
    const H5O_layout_chunk_t  *layout;  
    const H5O_storage_chunk_t *storage; 
    const hsize_t             *scaled;  
} H5D_chunk_common_ud_t;

typedef struct H5D_chunk_ud_t {
    
    H5D_chunk_common_ud_t common; 

    
    unsigned    idx_hint;         
    H5F_block_t chunk_block;      
    unsigned    filter_mask;      
    bool        new_unfilt_chunk; 
    hsize_t     chunk_idx;        
} H5D_chunk_ud_t;

typedef int (*H5D_chunk_cb_func_t)(const H5D_chunk_rec_t *chunk_rec, void *udata);

typedef herr_t (*H5D_chunk_init_func_t)(const H5D_chk_idx_info_t *idx_info, const H5S_t *space,
                                        haddr_t dset_ohdr_addr);
typedef herr_t (*H5D_chunk_create_func_t)(const H5D_chk_idx_info_t *idx_info);
typedef herr_t (*H5D_chunk_open_func_t)(const H5D_chk_idx_info_t *idx_info);
typedef herr_t (*H5D_chunk_close_func_t)(const H5D_chk_idx_info_t *idx_info);
typedef herr_t (*H5D_chunk_is_open_func_t)(const H5D_chk_idx_info_t *idx_info, bool *is_open);
typedef bool (*H5D_chunk_is_space_alloc_func_t)(const H5O_storage_chunk_t *storage);
typedef herr_t (*H5D_chunk_insert_func_t)(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata,
                                          const H5D_t *dset);
typedef herr_t (*H5D_chunk_get_addr_func_t)(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata);
typedef herr_t (*H5D_chunk_load_metadata_func_t)(const H5D_chk_idx_info_t *idx_info);
typedef herr_t (*H5D_chunk_resize_func_t)(H5O_layout_chunk_t *layout);
typedef int (*H5D_chunk_iterate_func_t)(const H5D_chk_idx_info_t *idx_info, H5D_chunk_cb_func_t chunk_cb,
                                        void *chunk_udata);
typedef herr_t (*H5D_chunk_remove_func_t)(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata);
typedef herr_t (*H5D_chunk_delete_func_t)(const H5D_chk_idx_info_t *idx_info);
typedef herr_t (*H5D_chunk_copy_setup_func_t)(const H5D_chk_idx_info_t *idx_info_src,
                                              const H5D_chk_idx_info_t *idx_info_dst);
typedef herr_t (*H5D_chunk_copy_shutdown_func_t)(H5O_storage_chunk_t *storage_src,
                                                 H5O_storage_chunk_t *storage_dst);
typedef herr_t (*H5D_chunk_size_func_t)(const H5D_chk_idx_info_t *idx_info, hsize_t *idx_size);
typedef herr_t (*H5D_chunk_reset_func_t)(H5O_storage_chunk_t *storage, bool reset_addr);
typedef herr_t (*H5D_chunk_dump_func_t)(const H5O_storage_chunk_t *storage, FILE *stream);
typedef herr_t (*H5D_chunk_dest_func_t)(const H5D_chk_idx_info_t *idx_info);

typedef struct H5D_chunk_ops_t {
    bool                     can_swim; 
    H5D_chunk_init_func_t    init;     
    H5D_chunk_create_func_t  create;   
    H5D_chunk_open_func_t    open;     
    H5D_chunk_close_func_t   close;    
    H5D_chunk_is_open_func_t is_open;  
    H5D_chunk_is_space_alloc_func_t
                              is_space_alloc; 
    H5D_chunk_insert_func_t   insert;         
    H5D_chunk_get_addr_func_t get_addr;       
    H5D_chunk_load_metadata_func_t
        load_metadata; 
    H5D_chunk_resize_func_t     resize;     
    H5D_chunk_iterate_func_t    iterate;    
    H5D_chunk_remove_func_t     remove;     
    H5D_chunk_delete_func_t     idx_delete; 
    H5D_chunk_copy_setup_func_t copy_setup; 
    H5D_chunk_copy_shutdown_func_t
                           copy_shutdown; 
    H5D_chunk_size_func_t  size;          
    H5D_chunk_reset_func_t reset;         
    H5D_chunk_dump_func_t  dump;          
    H5D_chunk_dest_func_t  dest;          
} H5D_chunk_ops_t;

typedef struct H5D_chunk_map_t {
    unsigned f_ndims; 

    H5S_t         *mchunk_tmpl; 
    H5S_sel_iter_t mem_iter;    
    unsigned       m_ndims;     
    H5S_sel_type   msel_type;   
    H5S_sel_type   fsel_type;   

    H5SL_t *dset_sel_pieces; 

    H5S_t            *single_space;      
    H5D_piece_info_t *single_piece_info; 
    bool              use_single;        

    hsize_t           last_index;      
    H5D_piece_info_t *last_piece_info; 

    hsize_t chunk_dim[H5O_LAYOUT_NDIMS]; 
} H5D_chunk_map_t;

typedef struct H5D_chunk_cached_t {
    bool     valid;                    
    hsize_t  scaled[H5O_LAYOUT_NDIMS]; 
    haddr_t  addr;                     
    hsize_t  nbytes;                   
    hsize_t  chunk_idx;                
    unsigned filter_mask;              
} H5D_chunk_cached_t;

typedef struct H5D_virtual_held_file_t {
    H5F_t                          *file; 
    struct H5D_virtual_held_file_t *next; 
} H5D_virtual_held_file_t;

struct H5D_rdcc_ent_t; 
typedef struct H5D_rdcc_t {
    struct {
        unsigned ninits;   
        unsigned nhits;    
        unsigned nmisses;  
        unsigned nflushes; 
    } stats;
    size_t                 nbytes_max; 
    size_t                 nslots;     
    double                 w0;         
    struct H5D_rdcc_ent_t *head;       
    struct H5D_rdcc_ent_t *tail;       
    struct H5D_rdcc_ent_t
        *tmp_head; 
    size_t                  nbytes_used;       
    int                     nused;             
    H5D_chunk_cached_t      last;              
    struct H5D_rdcc_ent_t **slot;              
    H5SL_t                 *sel_chunks;        
    H5S_t                  *single_space;      
    H5D_piece_info_t       *single_piece_info; 

    
    hsize_t  scaled_dims[H5S_MAX_RANK];        
    hsize_t  scaled_power2up[H5S_MAX_RANK];    
    unsigned scaled_encode_bits[H5S_MAX_RANK]; 
} H5D_rdcc_t;

typedef struct H5D_sieve_buf_t {
    unsigned char *sieve_buf;      
    haddr_t        sieve_loc;      
    size_t         sieve_size;     
    size_t         sieve_buf_size; 
    bool           sieve_dirty;    
} H5D_sieve_buf_t;

struct H5D_shared_t {
    size_t           fo_count;              
    bool             closing;               
    hid_t            type_id;               
    H5T_t           *type;                  
    H5S_t           *space;                 
    hid_t            dcpl_id;               
    hid_t            dapl_id;               
    H5D_dcpl_cache_t dcpl_cache;            
    H5O_layout_t     layout;                
    bool             layout_copied_to_dcpl; 
    bool             checked_filters;       

    
    unsigned ndims;                       
    hsize_t  curr_dims[H5S_MAX_RANK];     
    hsize_t  curr_power2up[H5S_MAX_RANK]; 
    hsize_t  max_dims[H5S_MAX_RANK];      

    
    struct {
        H5D_sieve_buf_t sieve; 
        H5D_rdcc_t      chunk; 
    } cache;

    H5D_append_flush_t append_flush;   
    char              *extfile_prefix; 
    char              *vds_prefix;     
};

struct H5D_t {
    H5O_loc_t     oloc;   
    H5G_name_t    path;   
    H5D_shared_t *shared; 
};

typedef enum {
    H5D_ALLOC_CREATE, 
    H5D_ALLOC_OPEN,   
    H5D_ALLOC_EXTEND, 
    H5D_ALLOC_WRITE   
} H5D_time_alloc_t;

struct H5D_obj_create_t {
    hid_t        type_id; 
    const H5S_t *space;   
    hid_t        dcpl_id; 
    hid_t        dapl_id; 
};

typedef struct H5D_fill_buf_info_t {
    H5MM_allocate_t fill_alloc_func; 
    void           *fill_alloc_info; 
    H5MM_free_t     fill_free_func;  
    void           *fill_free_info;  
    H5T_path_t
        *fill_to_mem_tpath; 
    H5T_path_t *mem_to_dset_tpath; 
    const H5O_fill_t *fill;        
    void             *fill_buf;    
    size_t            fill_buf_size;                 
    bool              use_caller_fill_buf;           
    void             *bkg_buf;                       
    size_t            bkg_buf_size;                  
    H5T_t            *mem_type;                      
    const H5T_t      *file_type;                     
    size_t            mem_elmt_size, file_elmt_size; 
    size_t            max_elmt_size;                 
    size_t            elmts_per_buf;                 
    bool has_vlen_fill_type; 
} H5D_fill_buf_info_t;

H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_CONTIG[1];
H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_EFL[1];
H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_COMPACT[1];
H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_CHUNK[1];
H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_VIRTUAL[1];

H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_BTREE[1];
H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_NONE[1];
H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_SINGLE[1];
H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_EARRAY[1];
H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_FARRAY[1];
H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_BT2[1];

H5_DLLVAR const H5B2_class_t H5D_BT2[1];
H5_DLLVAR const H5B2_class_t H5D_BT2_FILT[1];

H5_DLLVAR const unsigned H5O_layout_ver_bounds[H5F_LIBVER_NBOUNDS + 1];

H5_DLL H5D_t  *H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, hid_t dapl_id);
H5_DLL H5D_t  *H5D__create_named(const H5G_loc_t *loc, const char *name, hid_t type_id, const H5S_t *space,
                                 hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id);
H5_DLL H5D_t  *H5D__open_name(const H5G_loc_t *loc, const char *name, hid_t dapl_id);
H5_DLL hid_t   H5D__get_space(const H5D_t *dset);
H5_DLL hid_t   H5D__get_type(const H5D_t *dset);
H5_DLL herr_t  H5D__get_space_status(const H5D_t *dset, H5D_space_status_t *allocation);
H5_DLL herr_t  H5D__alloc_storage(H5D_t *dset, H5D_time_alloc_t time_alloc, bool full_overwrite,
                                  hsize_t old_dim[]);
H5_DLL herr_t  H5D__get_storage_size(const H5D_t *dset, hsize_t *storage_size);
H5_DLL herr_t  H5D__get_chunk_storage_size(H5D_t *dset, const hsize_t *offset, hsize_t *storage_size);
H5_DLL herr_t  H5D__chunk_index_empty(const H5D_t *dset, bool *empty);
H5_DLL herr_t  H5D__get_num_chunks(const H5D_t *dset, const H5S_t *space, hsize_t *nchunks);
H5_DLL herr_t  H5D__get_chunk_info(const H5D_t *dset, const H5S_t *space, hsize_t chk_idx, hsize_t *coord,
                                   unsigned *filter_mask, haddr_t *offset, hsize_t *size);
H5_DLL herr_t  H5D__get_chunk_info_by_coord(const H5D_t *dset, const hsize_t *coord, unsigned *filter_mask,
                                            haddr_t *addr, hsize_t *size);
H5_DLL herr_t  H5D__chunk_iter(H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data);
H5_DLL haddr_t H5D__get_offset(const H5D_t *dset);
H5_DLL herr_t  H5D__vlen_get_buf_size(H5D_t *dset, hid_t type_id, hid_t space_id, hsize_t *size);
H5_DLL herr_t  H5D__vlen_get_buf_size_gen(H5VL_object_t *vol_obj, hid_t type_id, hid_t space_id,
                                          hsize_t *size);
H5_DLL herr_t  H5D__set_extent(H5D_t *dataset, const hsize_t *size);
H5_DLL herr_t  H5D__flush_sieve_buf(H5D_t *dataset);
H5_DLL herr_t  H5D__flush_real(H5D_t *dataset);
H5_DLL herr_t  H5D__flush(H5D_t *dset, hid_t dset_id);
H5_DLL herr_t  H5D__mark(const H5D_t *dataset, unsigned flags);
H5_DLL herr_t  H5D__refresh(H5D_t *dataset, hid_t dset_id);

H5_DLL herr_t H5D__format_convert(H5D_t *dataset);

H5_DLL herr_t H5D__read(size_t count, H5D_dset_io_info_t *dset_info);
H5_DLL herr_t H5D__write(size_t count, H5D_dset_io_info_t *dset_info);

H5_DLL herr_t H5D__select_read(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info);
H5_DLL herr_t H5D__select_write(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info);

H5_DLL herr_t H5D_select_io_mem(void *dst_buf, H5S_t *dst_space, const void *src_buf, H5S_t *src_space,
                                size_t elmt_size, size_t nelmts);

H5_DLL herr_t H5D__scatter_mem(const void *_tscat_buf, H5S_sel_iter_t *iter, size_t nelmts, void *_buf);
H5_DLL size_t H5D__gather_mem(const void *_buf, H5S_sel_iter_t *iter, size_t nelmts,
                              void *_tgath_buf );
H5_DLL herr_t H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info);
H5_DLL herr_t H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info);
H5_DLL herr_t H5D__scatgath_read_select(H5D_io_info_t *io_info);
H5_DLL herr_t H5D__scatgath_write_select(H5D_io_info_t *io_info);

H5_DLL herr_t H5D__layout_set_io_ops(const H5D_t *dataset);
H5_DLL size_t H5D__layout_meta_size(const H5F_t *f, const H5O_layout_t *layout, bool include_compact_data);
H5_DLL herr_t H5D__layout_oh_create(H5F_t *file, H5O_t *oh, H5D_t *dset, hid_t dapl_id);
H5_DLL herr_t H5D__layout_oh_read(H5D_t *dset, hid_t dapl_id, H5P_genplist_t *plist);
H5_DLL herr_t H5D__layout_oh_write(const H5D_t *dataset, H5O_t *oh, unsigned update_flags);

H5_DLL herr_t H5D__contig_alloc(H5F_t *f, H5O_storage_contig_t *storage);
H5_DLL bool   H5D__contig_is_space_alloc(const H5O_storage_t *storage);
H5_DLL bool   H5D__contig_is_data_cached(const H5D_shared_t *shared_dset);
H5_DLL herr_t H5D__contig_fill(H5D_t *dset);
H5_DLL herr_t H5D__contig_read(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
H5_DLL herr_t H5D__contig_write(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
H5_DLL herr_t H5D__contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, H5F_t *f_dst,
                               H5O_storage_contig_t *storage_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info);
H5_DLL herr_t H5D__contig_delete(H5F_t *f, const H5O_storage_t *store);
H5_DLL herr_t H5D__contig_check(const H5F_t *f, const H5O_layout_t *layout, const H5S_extent_t *extent,
                                const H5T_t *dt);

H5_DLL htri_t H5D__chunk_cacheable(const H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info, haddr_t caddr,
                                   bool write_op);
H5_DLL herr_t H5D__chunk_create(const H5D_t *dset );
H5_DLL herr_t H5D__chunk_set_info(const H5D_t *dset);
H5_DLL bool   H5D__chunk_is_space_alloc(const H5O_storage_t *storage);
H5_DLL bool   H5D__chunk_is_data_cached(const H5D_shared_t *shared_dset);
H5_DLL herr_t H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, H5D_chunk_ud_t *udata);
H5_DLL herr_t H5D__chunk_allocated(const H5D_t *dset, hsize_t *nbytes);
H5_DLL herr_t H5D__chunk_allocate(const H5D_t *dset, bool full_overwrite, const hsize_t old_dim[]);
H5_DLL herr_t H5D__chunk_file_alloc(const H5D_chk_idx_info_t *idx_info, const H5F_block_t *old_chunk,
                                    H5F_block_t *new_chunk, bool *need_insert, const hsize_t *scaled);
H5_DLL void  *H5D__chunk_mem_alloc(size_t size, void *pline) H5_ATTR_MALLOC;
H5_DLL void   H5D__chunk_mem_free(void *chk, void *pline);
H5_DLL void  *H5D__chunk_mem_xfree(void *chk, const void *pline);
H5_DLL void  *H5D__chunk_mem_realloc(void *chk, size_t size, const H5O_pline_t *pline);
H5_DLL herr_t H5D__chunk_update_old_edge_chunks(H5D_t *dset, hsize_t old_dim[]);
H5_DLL bool   H5D__chunk_is_partial_edge_chunk(unsigned dset_ndims, const hsize_t *chunk_dims,
                                               const hsize_t *chunk_scaled, const hsize_t *dset_dims);
H5_DLL herr_t H5D__chunk_prune_by_extent(H5D_t *dset, const hsize_t *old_dim);
#ifdef H5_HAVE_PARALLEL
H5_DLL herr_t H5D__chunk_addrmap(const H5D_t *dset, haddr_t chunk_addr[]);
#endif 
H5_DLL herr_t H5D__chunk_update_cache(H5D_t *dset);
H5_DLL herr_t H5D__chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst, H5O_layout_t *layout_dst,
                              const H5S_extent_t *ds_extent_src, H5T_t *dt_src, const H5O_pline_t *pline_src,
                              H5O_copy_t *cpy_info);
H5_DLL herr_t H5D__chunk_bh_info(const H5O_loc_t *loc, H5O_t *oh, H5O_layout_t *layout, hsize_t *btree_size);
H5_DLL herr_t H5D__chunk_dump_index(H5D_t *dset, FILE *stream);
H5_DLL herr_t H5D__chunk_delete(H5F_t *f, H5O_t *oh, H5O_layout_t *layout);
H5_DLL herr_t H5D__chunk_get_offset_copy(const H5D_t *dset, const hsize_t *offset, hsize_t *offset_copy);
H5_DLL herr_t H5D__chunk_direct_write(H5D_t *dset, uint32_t filters, hsize_t *offset, size_t data_size,
                                      const void *buf);
H5_DLL herr_t H5D__chunk_direct_read(const H5D_t *dset, hsize_t *offset, uint32_t *filters, void *buf,
                                     size_t *nalloc);
#ifdef H5D_CHUNK_DEBUG
H5_DLL herr_t H5D__chunk_stats(const H5D_t *dset, bool headers);
#endif 

H5_DLL herr_t H5D__chunk_format_convert(H5D_t *dset, H5D_chk_idx_info_t *idx_info,
                                        H5D_chk_idx_info_t *new_idx_info);

H5_DLL herr_t H5D__compact_fill(const H5D_t *dset);
H5_DLL herr_t H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *storage_src, H5F_t *f_dst,
                                H5O_storage_compact_t *storage_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info);

H5_DLL herr_t H5D__virtual_store_layout(H5F_t *f, H5O_layout_t *layout);
H5_DLL herr_t H5D__virtual_load_layout(H5F_t *f, H5O_layout_t *layout);
H5_DLL herr_t H5D__virtual_copy_layout(H5O_layout_t *layout);
H5_DLL herr_t H5D__virtual_set_extent_unlim(const H5D_t *dset);
H5_DLL herr_t H5D__virtual_reset_layout(H5O_layout_t *layout);
H5_DLL herr_t H5D__virtual_delete(H5F_t *f, H5O_storage_t *storage);
H5_DLL herr_t H5D__virtual_copy(H5F_t *f_src, H5O_layout_t *layout_dst);
H5_DLL herr_t H5D__virtual_hold_source_dset_files(const H5D_t *dset, H5D_virtual_held_file_t **head);
H5_DLL herr_t H5D__virtual_refresh_source_dsets(H5D_t *dset);
H5_DLL herr_t H5D__virtual_release_source_dset_files(H5D_virtual_held_file_t *head);

H5_DLL bool   H5D__efl_is_space_alloc(const H5O_storage_t *storage);
H5_DLL herr_t H5D__efl_bh_info(H5F_t *f, H5O_efl_t *efl, hsize_t *heap_size);

H5_DLL herr_t H5D__fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_type,
                        H5S_t *space);
H5_DLL herr_t H5D__fill_init(H5D_fill_buf_info_t *fb_info, void *caller_fill_buf, H5MM_allocate_t alloc_func,
                             void *alloc_info, H5MM_free_t free_func, void *free_info, const H5O_fill_t *fill,
                             const H5T_t *dset_type, size_t nelmts, size_t min_buf_size);
H5_DLL herr_t H5D__fill_refill_vl(H5D_fill_buf_info_t *fb_info, size_t nelmts);
H5_DLL herr_t H5D__fill_term(H5D_fill_buf_info_t *fb_info);

#ifdef H5_HAVE_PARALLEL

#ifdef H5D_DEBUG
#ifndef H5Dmpio_DEBUG
#define H5Dmpio_DEBUG
#endif 
#endif 

H5_DLL herr_t H5D__mpio_select_read(const H5D_io_info_t *io_info, hsize_t nelmts, H5S_t *file_space,
                                    H5S_t *mem_space);

H5_DLL herr_t H5D__mpio_select_write(const H5D_io_info_t *io_info, hsize_t nelmts, H5S_t *file_space,
                                     H5S_t *mem_space);

H5_DLL herr_t H5D__collective_read(H5D_io_info_t *io_info);
H5_DLL herr_t H5D__collective_write(H5D_io_info_t *io_info);

H5_DLL htri_t H5D__mpio_opt_possible(H5D_io_info_t *io_info);
H5_DLL herr_t H5D__mpio_get_no_coll_cause_strings(char *local_cause, size_t local_cause_len,
                                                  char *global_cause, size_t global_cause_len);

#endif 

H5_DLL herr_t H5D__free_piece_info(void *item, void *key, void *opdata);

#ifdef H5D_TESTING
H5_DLL herr_t H5D__layout_version_test(hid_t did, unsigned *version);
H5_DLL herr_t H5D__layout_contig_size_test(hid_t did, hsize_t *size);
H5_DLL herr_t H5D__layout_compact_dirty_test(hid_t did, bool *dirty);
H5_DLL herr_t H5D__layout_idx_type_test(hid_t did, H5D_chunk_index_t *idx_type);
H5_DLL herr_t H5D__layout_type_test(hid_t did, H5D_layout_t *layout_type);
H5_DLL herr_t H5D__current_cache_size_test(hid_t did, size_t *nbytes_used, int *nused);
#endif 

#endif 
