diff options
Diffstat (limited to 'src/H5HFsection.c')
-rw-r--r-- | src/H5HFsection.c | 595 |
1 files changed, 595 insertions, 0 deletions
diff --git a/src/H5HFsection.c b/src/H5HFsection.c new file mode 100644 index 0000000..6cbe4cb --- /dev/null +++ b/src/H5HFsection.c @@ -0,0 +1,595 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> + * Monday, May 1, 2006 + * + * Purpose: Free space section routines for fractal heaps. + * + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5HF_PACKAGE /*suppress error about including H5HFpkg */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5HFpkg.h" /* Fractal heaps */ + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ +static herr_t H5HF_sect_single_deserialize(H5FS_section_class_t *sect_cls, + const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size, + H5FS_section_info_t **sect); +static herr_t H5HF_sect_range_init(H5FS_section_class_t *cls, const void *udata); +static herr_t H5HF_sect_range_serialize(const H5FS_section_info_t *sect, uint8_t *buf); +static herr_t H5HF_sect_range_deserialize(H5FS_section_class_t *sect_cls, + const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size, + H5FS_section_info_t **sect); +static herr_t H5HF_sect_range_debug(const H5FS_section_info_t *sect, + FILE *stream, int indent, int fwidth); +static herr_t H5HF_sect_indirect_init(H5FS_section_class_t *cls, const void *udata); +static herr_t H5HF_sect_indirect_serialize(const H5FS_section_info_t *sect, uint8_t *buf); +static herr_t H5HF_sect_indirect_deserialize(H5FS_section_class_t *sect_cls, + const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size, + H5FS_section_info_t **sect); +static herr_t H5HF_sect_indirect_debug(const H5FS_section_info_t *sect, + FILE *stream, int indent, int fwidth); + + +/*********************/ +/* Package Variables */ +/*********************/ + +/* Class info for "single" free space sections */ +/* (No callbacks necessary) */ +H5FS_section_class_t H5FS_SECT_CLS_FHEAP_SINGLE[1] = {{ + H5FS_SECT_FHEAP_SINGLE, + 0, + NULL, + NULL, + H5HF_sect_single_deserialize, + NULL, +}}; + +/* Class info for "range" free space sections */ +H5FS_section_class_t H5FS_SECT_CLS_FHEAP_RANGE[1] = {{ + H5FS_SECT_FHEAP_RANGE, + 0, + H5HF_sect_range_init, + H5HF_sect_range_serialize, + H5HF_sect_range_deserialize, + H5HF_sect_range_debug, +}}; + +/* Class info for "indirect" free space sections */ +H5FS_section_class_t H5FS_SECT_CLS_FHEAP_INDIRECT[1] = {{ + H5FS_SECT_FHEAP_INDIRECT, + 0, + H5HF_sect_indirect_init, + H5HF_sect_indirect_serialize, + H5HF_sect_indirect_deserialize, + H5HF_sect_indirect_debug, +}}; + +/* Declare a free list to manage the H5HF_free_section_t struct */ +H5FL_DEFINE(H5HF_free_section_t); + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5HF_free_section_free_cb + * + * Purpose: Free a free section node + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, March 13, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_free_section_free_cb(void *_sect, void UNUSED *key, void UNUSED *op_data) +{ + H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; + herr_t ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_free_section_free_cb) + + HDassert(sect); + + /* Check for live reference to an indirect block */ + if(sect->sect_info.state == H5FS_SECT_LIVE) { + H5HF_indirect_t *iblock; /* Indirect block referenced */ + + /* Find indirect block that free section references */ + switch(sect->sect_info.cls->type) { + case H5FS_SECT_FHEAP_SINGLE: + iblock = sect->u.single.parent; + break; + + case H5FS_SECT_FHEAP_RANGE: + iblock = sect->u.range.iblock; + break; + + case H5FS_SECT_FHEAP_INDIRECT: + iblock = sect->u.indirect.iblock; + break; + } /* end switch */ + + /* Release indirect block, if there was one */ + if(iblock) + if(H5HF_iblock_decr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") + } /* end if */ + + /* Release the sections */ + H5FL_FREE(H5HF_free_section_t, sect); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_free_section_free_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_sect_node_alloc + * + * Purpose: Allocate a free space section node of a particular type + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Saturday, May 13, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_node_alloc(H5FS_section_class_t *sect_cls, unsigned sect_type, + haddr_t sect_addr, hsize_t sect_size, H5FS_section_info_t **sect) +{ + H5HF_free_section_t *new_sect; /* New section */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_node_alloc) + + /* Check arguments. */ + HDassert(H5F_addr_defined(sect_addr)); + HDassert(sect_size); + HDassert(sect); + + /* Create free list section node */ + if(NULL == (new_sect = H5FL_MALLOC(H5HF_free_section_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct block free list section") + + /* Set the information passed in */ + new_sect->sect_info.addr = sect_addr; + new_sect->sect_info.size = sect_size; + + /* Set the section's class & state */ + new_sect->sect_info.cls = §_cls[sect_type]; + new_sect->sect_info.state = H5FS_SECT_SERIALIZED; + + /* Update the return parameter */ + *sect = (H5FS_section_info_t *)new_sect; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_sect_node_alloc() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_sect_single_deserialize + * + * Purpose: Deserialize a buffer into a "live" single section + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, May 1, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_single_deserialize(H5FS_section_class_t *sect_cls, + const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size, + H5FS_section_info_t **sect) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_single_deserialize) + + /* Check arguments. */ + HDassert(buf); + HDassert(H5F_addr_defined(sect_addr)); + HDassert(sect_size); + HDassert(sect); + + /* Create free list section node */ + if(H5HF_sect_node_alloc(sect_cls, H5FS_SECT_FHEAP_SINGLE, sect_addr, sect_size, sect) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "allocation failed for direct block free list section") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_sect_single_deserialize() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_sect_range_init + * + * Purpose: Initialize the "range" class structure + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, May 1, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_range_init(H5FS_section_class_t *cls, const void UNUSED *udata) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_range_init) + + /* Check arguments. */ + HDassert(cls); + + /* Set the size of all serialized objects of this class of sections */ + cls->serial_size = 2 /* Row */ + + 2 /* Column */ + + 2; /* # of entries */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_sect_range_init() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_sect_range_serialize + * + * Purpose: Serialize a "live" range section into a buffer + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, May 1, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_range_serialize(const H5FS_section_info_t *_sect, uint8_t *buf) +{ + const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_range_serialize) + + /* Check arguments. */ + HDassert(buf); + HDassert(sect); + + /* Range's row */ + UINT16ENCODE(buf, sect->u.range.row); + + /* Range's column */ + UINT16ENCODE(buf, sect->u.range.col); + + /* Range's # of entries */ + UINT16ENCODE(buf, sect->u.range.num_entries); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_sect_range_serialize() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_sect_range_deserialize + * + * Purpose: Deserialize a buffer into a "live" range section + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, May 1, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_range_deserialize(H5FS_section_class_t *sect_cls, + const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size, + H5FS_section_info_t **sect) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_range_deserialize) + + /* Check arguments. */ + HDassert(buf); + HDassert(H5F_addr_defined(sect_addr)); + HDassert(sect_size); + HDassert(sect); + + /* Create free list section node */ + if(H5HF_sect_node_alloc(sect_cls, H5FS_SECT_FHEAP_RANGE, sect_addr, sect_size, sect) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "allocation failed for direct block free list section") + + /* Range's row */ + UINT16DECODE(buf, ((H5HF_free_section_t *)*sect)->u.range.row); + + /* Range's column */ + UINT16DECODE(buf, ((H5HF_free_section_t *)*sect)->u.range.col); + + /* Range's # of entries */ + UINT16DECODE(buf, ((H5HF_free_section_t *)*sect)->u.range.num_entries); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_sect_range_deserialize() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_sect_range_debug + * + * Purpose: Dump debugging information about an range free space section + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Saturday, May 13, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_range_debug(const H5FS_section_info_t *_sect, + FILE *stream, int indent, int fwidth) +{ + const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Section to dump info */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_range_debug) + + /* Check arguments. */ + HDassert(sect); + + /* Print range section information */ + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Row:", + sect->u.range.row); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Column:", + sect->u.range.col); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Number of entries:", + sect->u.range.num_entries); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_sect_range_debug() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_sect_indirect_init + * + * Purpose: Initialize the "indirect" class structure + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, May 1, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_indirect_init(H5FS_section_class_t *cls, const void UNUSED *udata) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_init) + + /* Check arguments. */ + HDassert(cls); + + /* Set the size of all serialized objects of this class of sections */ + cls->serial_size = 2 /* Row */ + + 2 /* Column */ + + 2 /* # of entries */ + + 2 /* Indirect row */ + + 2; /* Indirect # of rows */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_sect_indirect_init() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_sect_indirect_serialize + * + * Purpose: Serialize a "live" indirect section into a buffer + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, May 1, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_indirect_serialize(const H5FS_section_info_t *_sect, uint8_t *buf) +{ + const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_serialize) + + /* Check arguments. */ + HDassert(buf); + HDassert(_sect); + + /* Range's row */ + UINT16ENCODE(buf, sect->u.indirect.row); + + /* Range's column */ + UINT16ENCODE(buf, sect->u.indirect.col); + + /* Range's # of entries */ + UINT16ENCODE(buf, sect->u.indirect.num_entries); + + /* Range's indirect row */ + UINT16ENCODE(buf, sect->u.indirect.indir_row); + + /* Range's indirect # of rows */ + UINT16ENCODE(buf, sect->u.indirect.indir_nrows); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_sect_indirect_serialize() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_sect_indirect_deserialize + * + * Purpose: Deserialize a buffer into a "live" indirect section + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, May 1, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_indirect_deserialize(H5FS_section_class_t *sect_cls, + const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size, + H5FS_section_info_t **sect) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_deserialize) + + /* Check arguments. */ + HDassert(buf); + HDassert(H5F_addr_defined(sect_addr)); + HDassert(sect_size); + HDassert(sect); + + /* Create free list section node */ + if(H5HF_sect_node_alloc(sect_cls, H5FS_SECT_FHEAP_INDIRECT, sect_addr, sect_size, sect) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "allocation failed for direct block free list section") + + /* Range's row */ + UINT16DECODE(buf, ((H5HF_free_section_t *)*sect)->u.indirect.row); + + /* Range's column */ + UINT16DECODE(buf, ((H5HF_free_section_t *)*sect)->u.indirect.col); + + /* Range's # of entries */ + UINT16DECODE(buf, ((H5HF_free_section_t *)*sect)->u.indirect.num_entries); + + /* Range's indirect row */ + UINT16DECODE(buf, ((H5HF_free_section_t *)*sect)->u.indirect.indir_row); + + /* Range's indirect # of rows */ + UINT16DECODE(buf, ((H5HF_free_section_t *)*sect)->u.indirect.indir_nrows); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_sect_indirect_deserialize() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_sect_indirect_debug + * + * Purpose: Dump debugging information about an indirect free space section + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Saturday, May 13, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_indirect_debug(const H5FS_section_info_t *_sect, + FILE *stream, int indent, int fwidth) +{ + const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Section to dump info */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_debug) + + /* Check arguments. */ + HDassert(sect); + + /* Print indirect section information */ + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Row:", + sect->u.indirect.row); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Column:", + sect->u.indirect.col); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Number of entries:", + sect->u.indirect.num_entries); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Indirect row:", + sect->u.indirect.indir_row); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Indirect number of rows:", + sect->u.indirect.indir_nrows); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_sect_indirect_debug() */ + |