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

#ifndef H5MFpkg_H
#define H5MFpkg_H

#include "H5MFprivate.h"

#include "H5FSprivate.h" 

#define H5MF_FSPACE_SECT_SIMPLE 0

#define H5MF_FSPACE_SECT_SMALL 1

#define H5MF_FSPACE_SECT_LARGE 2

#define H5MF_SECT_CLASS_TYPE(F, S)                                                                           \
    ((H5F_PAGED_AGGR(F))                                                                                     \
         ? ((S >= (F)->shared->fs_page_size) ? H5MF_FSPACE_SECT_LARGE : H5MF_FSPACE_SECT_SMALL)              \
         : H5MF_FSPACE_SECT_SIMPLE)

#define H5MF_SECT_CLS_TYPE(F, S)                                                                             \
    ((H5F_PAGED_AGGR(F))                                                                                     \
         ? ((S >= (F)->shared->fs_page_size) ? H5MF_FSPACE_SECT_CLS_LARGE : H5MF_FSPACE_SECT_CLS_SMALL)      \
         : H5MF_FSPACE_SECT_CLS_SIMPLE)

#define H5MF_EOA_MISALIGN(F, E, A, FR)                                                                       \
    do {                                                                                                     \
        hsize_t m;                                                                                           \
                                                                                                             \
        if (H5_addr_gt((E), 0) && ((m) = ((E) + H5F_BASE_ADDR(F)) % (A)))                                    \
            (FR) = (A)-m;                                                                                    \
        else                                                                                                 \
            (FR) = 0;                                                                                        \
    } while (0)

typedef struct H5MF_free_section_t {
    H5FS_section_info_t sect_info; 
#ifdef NOT_YET
    union {
        struct {
            H5HF_indirect_t *parent;    
            unsigned         par_entry; 
        } single;
        struct {
            struct H5HF_free_section_t *under;       
            unsigned                    row;         
            unsigned                    col;         
            unsigned                    num_entries; 

            
            bool checked_out; 
        } row;
        struct {
            
            union {
                H5HF_indirect_t *iblock;     
                hsize_t          iblock_off; 
            } u;
            unsigned row;         
            unsigned col;         
            unsigned num_entries; 

            
            struct H5HF_free_section_t *parent;    
            unsigned                    par_entry; 
            hsize_t                     span_size; 
            unsigned iblock_entries; 
            unsigned rc;             
            unsigned dir_nrows;      
            struct H5HF_free_section_t **dir_rows;    
            unsigned                     indir_nents; 
            struct H5HF_free_section_t *
                *indir_ents; 
        } indirect;
    } u;
#endif 
} H5MF_free_section_t;

typedef enum {
    H5MF_SHRINK_EOA,              
    H5MF_SHRINK_AGGR_ABSORB_SECT, 
    H5MF_SHRINK_SECT_ABSORB_AGGR  
} H5MF_shrink_type_t;

typedef struct H5MF_sect_ud_t {
    
    H5F_t     *f;                     
    H5FD_mem_t alloc_type;            
    bool       allow_sect_absorb;     
    bool       allow_eoa_shrink_only; 

    
    H5MF_shrink_type_t shrink; 
    H5F_blk_aggr_t    *aggr;   
} H5MF_sect_ud_t;

typedef struct H5MF_fs_t {
    H5F_fs_state_t *fs_state;
    haddr_t        *fs_addr;
    H5FS_t        **fs_man;
    hsize_t         align_thres; 
    hsize_t         alignment;   
} H5MF_fs_t;

H5_DLLVAR const H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SIMPLE[1];
H5_DLLVAR const H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SMALL[1];
H5_DLLVAR const H5FS_section_class_t H5MF_FSPACE_SECT_CLS_LARGE[1];

H5_DLL herr_t H5MF__open_fstype(H5F_t *f, H5F_mem_page_t type);
H5_DLL herr_t H5MF__start_fstype(H5F_t *f, H5F_mem_page_t type);
H5_DLL htri_t H5MF__find_sect(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size, H5FS_t *fspace, haddr_t *addr);
H5_DLL herr_t H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_section_t *node,
                             bool *merged_or_shrunk);
H5_DLL void   H5MF__alloc_to_fs_type(H5F_shared_t *f_sh, H5FD_mem_t alloc_type, hsize_t size,
                                     H5F_mem_page_t *fs_type);

H5_DLL H5MF_free_section_t *H5MF__sect_new(unsigned ctype, haddr_t sect_off, hsize_t sect_size);
H5_DLL herr_t               H5MF__sect_free(H5FS_section_info_t *sect);

H5_DLL htri_t H5MF__aggr_try_extend(H5F_t *f, H5F_blk_aggr_t *aggr, H5FD_mem_t type, haddr_t abs_blk_end,
                                    hsize_t extra_requested);
H5_DLL htri_t H5MF__aggrs_try_shrink_eoa(H5F_t *f);
H5_DLL htri_t H5MF__aggr_can_absorb(const H5F_t *f, const H5F_blk_aggr_t *aggr,
                                    const H5MF_free_section_t *sect, H5MF_shrink_type_t *shrink);
H5_DLL herr_t H5MF__aggr_absorb(const H5F_t *f, H5F_blk_aggr_t *aggr, H5MF_free_section_t *sect,
                                bool allow_sect_absorb);
H5_DLL herr_t H5MF__aggr_query(const H5F_t *f, const H5F_blk_aggr_t *aggr, haddr_t *addr, hsize_t *size);

#ifdef H5MF_ALLOC_DEBUG_DUMP
H5_DLL herr_t H5MF__sects_dump(H5F_t *f, FILE *stream);
#endif 

#ifdef H5MF_TESTING
#endif 

#endif 
