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

#ifndef H5FSpkg_H
#define H5FSpkg_H

#include "H5FSprivate.h" 

#include "H5ACprivate.h" 
#include "H5SLprivate.h" 

#define H5FS_SIZEOF_CHKSUM 4

#define H5FS_METADATA_PREFIX_SIZE                                                                            \
    (H5_SIZEOF_MAGIC                                                                          \
     + 1                                                                                        \
     + H5FS_SIZEOF_CHKSUM                                                             \
    )

#define H5FS_HEADER_SIZE(f)                                                                                  \
    (                                                                           \
     H5FS_METADATA_PREFIX_SIZE                                                                               \
                                                                                                             \
                                                                      \
     + 1                                                                                      \
     + (unsigned)H5F_SIZEOF_SIZE(f)                                            \
     + (unsigned)H5F_SIZEOF_SIZE(f)                                         \
     + (unsigned)H5F_SIZEOF_SIZE(f)                                  \
     + (unsigned)H5F_SIZEOF_SIZE(f)                                         \
     + 2                                                                      \
     + 2                                                                                 \
     + 2                                                                                 \
     + 2                                             \
     + (unsigned)H5F_SIZEOF_SIZE(f)                                       \
     + (unsigned)H5F_SIZEOF_ADDR(f)                           \
     + (unsigned)H5F_SIZEOF_SIZE(f)                         \
     + (unsigned)H5F_SIZEOF_SIZE(f)                    \
    )

#define H5FS_SINFO_PREFIX_SIZE(f)                                                                            \
    (                                                                           \
     H5FS_METADATA_PREFIX_SIZE                                                                               \
                                                                                                             \
                                                         \
     + (unsigned)H5F_SIZEOF_ADDR(f)                     \
    )

typedef struct H5FS_hdr_cache_ud_t {
    H5F_t                       *f;              
    uint16_t                     nclasses;       
    const H5FS_section_class_t **classes;        
    void                        *cls_init_udata; 
    haddr_t                      addr;           
} H5FS_hdr_cache_ud_t;

typedef struct H5FS_sinfo_cache_ud_t {
    H5F_t  *f;      
    H5FS_t *fspace; 
} H5FS_sinfo_cache_ud_t;

typedef struct H5FS_bin_t {
    size_t  tot_sect_count;    
    size_t  serial_sect_count; 
    size_t  ghost_sect_count;  
    H5SL_t *bin_list;          
} H5FS_bin_t;

typedef struct H5FS_node_t {
    hsize_t sect_size;    
    size_t  serial_count; 
    size_t  ghost_count;  
    H5SL_t *sect_list;    
} H5FS_node_t;

typedef struct H5FS_sinfo_t {
    
    H5AC_info_t cache_info;

    
    H5FS_bin_t *bins; 

    
    bool     dirty;             
    unsigned nbins;             
    size_t   serial_size;       
    size_t   tot_size_count;    
    size_t   serial_size_count; 
    size_t   ghost_size_count;  
    unsigned sect_prefix_size;  
    unsigned sect_off_size;     
    unsigned sect_len_size;     
    H5FS_t  *fspace;            

    
    H5SL_t *merge_list; 
} H5FS_sinfo_t;

struct H5FS_t {
    
    H5AC_info_t cache_info;

    
    
    hsize_t tot_space;         
    hsize_t tot_sect_count;    
    hsize_t serial_sect_count; 
    hsize_t ghost_sect_count;  

    
    H5FS_client_t client;         
    uint16_t      nclasses;       
    unsigned      shrink_percent; 
    unsigned      expand_percent; 
    unsigned      max_sect_addr;  
    hsize_t       max_sect_size;  

    
    haddr_t sect_addr;       
    hsize_t sect_size;       
    hsize_t alloc_sect_size; 

    
    unsigned      rc;               
    haddr_t       addr;             
    size_t        hdr_size;         
    H5FS_sinfo_t *sinfo;            
    bool          swmr_write;       
    unsigned      sinfo_lock_count; 
    bool          sinfo_protected;  
    bool          sinfo_modified;   
    unsigned      sinfo_accmode;    
                                    
    
    size_t  max_cls_serial_size; 
    hsize_t alignment;           
    hsize_t align_thres;         

    
    H5FS_section_class_t *sect_cls; 
};

H5FL_EXTERN(H5FS_node_t);

H5FL_SEQ_EXTERN(H5FS_bin_t);

H5FL_EXTERN(H5FS_sinfo_t);

H5FL_EXTERN(H5FS_t);

H5_DLL herr_t H5FS__create_flush_depend(H5AC_info_t *parent_entry, H5AC_info_t *child_entry);
H5_DLL herr_t H5FS__destroy_flush_depend(H5AC_info_t *parent_entry, H5AC_info_t *child_entry);

H5_DLL H5FS_t *H5FS__new(const H5F_t *f, uint16_t nclasses, const H5FS_section_class_t *classes[],
                         void *cls_init_udata);
H5_DLL herr_t  H5FS__incr(H5FS_t *fspace);
H5_DLL herr_t  H5FS__decr(H5FS_t *fspace);
H5_DLL herr_t  H5FS__dirty(H5FS_t *fspace);

H5_DLL H5FS_sinfo_t *H5FS__sinfo_new(H5F_t *f, H5FS_t *fspace);

H5_DLL herr_t H5FS__hdr_dest(H5FS_t *hdr);
H5_DLL herr_t H5FS__sinfo_dest(H5FS_sinfo_t *sinfo);

#ifdef H5FS_DEBUG_ASSERT
H5_DLL void H5FS__assert(const H5FS_t *fspace);
H5_DLL void H5FS__sect_assert(const H5FS_t *fspace);
#endif 

#ifdef H5FS_TESTING
H5_DLL herr_t H5FS__get_cparam_test(const H5FS_t *fh, H5FS_create_t *cparam);
H5_DLL int    H5FS__cmp_cparam_test(const H5FS_create_t *cparam1, const H5FS_create_t *cparam2);
#endif 

#endif 
