diff options
Diffstat (limited to 'src/H5SH.c')
-rw-r--r-- | src/H5SH.c | 337 |
1 files changed, 0 insertions, 337 deletions
diff --git a/src/H5SH.c b/src/H5SH.c deleted file mode 100644 index 9c8e330..0000000 --- a/src/H5SH.c +++ /dev/null @@ -1,337 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * 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. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/*------------------------------------------------------------------------- - * - * Created: H5SH.c - * Mar 9 2005 - * Quincey Koziol <koziol@ncsa.uiuc.edu> - * - * Purpose: Implement "segmented heaps". These heaps are - * - *------------------------------------------------------------------------- - */ - -#define H5SH_PACKAGE /*suppress error about including H5SHpkg */ - -/* Private headers */ -#include "H5private.h" /* Generic Functions */ -#include "H5BTprivate.h" /* Block tracker */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5MFprivate.h" /* File memory management */ -#include "H5SHpkg.h" /* Segmented heap */ - -/* Local macros */ - -/* Local typedefs */ - -/* Information needed for extending a heap block during an allocation */ -typedef struct { - H5F_t *f; /* File to search for space within */ - hid_t dxpl_id; /* DXPL for allocation operation */ - haddr_t bt_free_addr; /* Location of free space B-tree */ - H5FD_mem_t file_mem_type; /* Type of file memory being used */ - hsize_t max_extend_size; /* Maximum size of a block to consider for extention */ - hsize_t space_needed; /* Amount of space to allocate */ - haddr_t loc; /* Location of space allocated */ - haddr_t extend_addr; /* Extended space address */ - hsize_t extend_size; /* Extended space size */ -} H5SH_extend_t; - -/* Local prototypes */ - -/* Package variables */ - -/* Declare a free list to manage the H5SH_t struct */ -H5FL_DEFINE(H5SH_t); - -/* Static variables */ - - -/*------------------------------------------------------------------------- - * Function: H5SH_create - * - * Purpose: Creates a new empty segmented heap in the file. - * - * Return: Non-negative on success (with address of new segmented heap - * filled in), negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Mar 23 2005 - * - * Changes: John Mainzer -- 6/7/05 - * Removed code modifying the is_dirty field of the cache - * info. Management of this field is in the process of - * being moved to the H5C code. - * - *------------------------------------------------------------------------- - */ -herr_t -H5SH_create(H5F_t *f, hid_t dxpl_id, haddr_t *addr_p, H5SH_data_type_t heap_type, - hsize_t min_size, hsize_t max_extend_size) -{ - H5SH_t *sh = NULL; /* Segmented heap info */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5SH_create, FAIL) - - /* - * Check arguments. - */ - HDassert(f); - HDassert(min_size > 0); - HDassert(max_extend_size >= min_size); - - /* - * Allocate file and memory data structures. - */ - if (NULL == (sh = H5FL_CALLOC(H5SH_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for segmented heap info") - - /* Assign internal information */ - sh->heap_type = heap_type; - if(sh->heap_type == H5SH_RAW) - sh->file_mem_type = H5FD_MEM_DRAW; - else - sh->file_mem_type = H5FD_MEM_SHEAP_BLOCK; - sh->min_size = min_size; - sh->max_extend_size = max_extend_size; - - /* Allocate space for the header on disk */ - if (HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_SHEAP_HDR, dxpl_id, (hsize_t)H5SH_SIZE(f)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for segmented heap info") - - /* Create a block tracker for storing heap block info */ - if (H5BT_create(f, dxpl_id, &sh->bt_heap_addr/*out*/) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create block tracker for storing heap block info") - - /* Create a block tracker for storing free space info */ - if (H5BT_create(f, dxpl_id, &sh->bt_free_addr/*out*/) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create block tracker for storing free space info") - - /* Cache the new segmented heap node */ - if (H5AC_set(f, dxpl_id, H5AC_SGHP, *addr_p, sh, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add segmented heap info to cache") - -done: - if (ret_value<0) { - if (sh) - (void)H5SH_cache_dest(f, sh); - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SH_create() */ - - -/*------------------------------------------------------------------------- - * Function: H5SH_alloc_extend_cb - * - * Purpose: Extend an existing heap block if possible - * - * Return: Non-negative on success (setting flag to indicate block - * was extended), negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Mar 25 2005 - * - *------------------------------------------------------------------------- - */ -static int -H5SH_alloc_extend_cb(const H5BT_blk_info_t *record, void *_op_data) -{ - H5SH_extend_t *ex_info = (H5SH_extend_t *)_op_data; - htri_t extendable; /* Is block extendable */ - int ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5SH_alloc_extend_cb) - - /* Check if we are allowed to extend this heap block */ - if(record->len < ex_info->max_extend_size) { - H5BT_blk_info_t free_block; /* Block info for free space */ - hsize_t space_needed; /* Space needed to extend block */ - hbool_t use_free_space = FALSE; /* Flag to indicate that free space should be used */ - - /* Set the amount of space needed */ - space_needed = ex_info->space_needed; - - /* Find first free space block before end of extendable block */ - free_block.addr = HADDR_UNDEF; - if(H5BT_neighbor(ex_info->f, ex_info->dxpl_id, ex_info->bt_free_addr, - H5BT_COMPARE_LESS, (record->addr + record->len + 1), - &free_block) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, H5BT_ITER_ERROR, "can't search for free space") - - /* Check if we can use free space for part of block to allocate */ - if(H5F_addr_defined(free_block.addr) && - (free_block.addr + free_block.len) == (record->addr + record->len)) { - use_free_space = TRUE; - space_needed -= free_block.len; - } /* end if */ - - /* Check if this heap block can be extended */ - if((extendable = H5MF_can_extend(ex_info->f, ex_info->file_mem_type, - record->addr, record->len, space_needed)) == TRUE) { - - /* Extend heap block in the file */ - if(H5MF_extend(ex_info->f, ex_info->file_mem_type, - record->addr, record->len, space_needed) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, H5BT_ITER_ERROR, "can't extend extendable heap block?") - - /* Set information to return from iterator */ - if(use_free_space) { - /* Remove block from free space tracker */ - if(H5BT_remove(ex_info->f, ex_info->dxpl_id, ex_info->bt_free_addr, - free_block.addr, free_block.len) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't remove free space block") - - ex_info->loc = free_block.addr; - } /* end if */ - else - ex_info->loc = record->addr + record->len; - - /* Set information about extension to block */ - ex_info->extend_addr = record->addr + record->len; - ex_info->extend_size = space_needed; - - ret_value = H5BT_ITER_STOP; - } /* end if */ - else if(extendable == FALSE) - ret_value = H5BT_ITER_CONT; - else - HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPARE, H5BT_ITER_ERROR, "can't check if heap block is extendable") - } /* end if */ - else - ret_value = H5BT_ITER_CONT; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SH_alloc_extend_cb() */ - - -/*------------------------------------------------------------------------- - * Function: H5SH_alloc - * - * Purpose: Allocate space for a new object in a segmented heap - * - * Return: Non-negative on success (with address of new object - * filled in), negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Mar 25 2005 - * - * Modifications: - * - * John Mainzer, 6/16/05 - * Modified the function to use the new dirtied parameter of - * of H5AC_unprotect() instead of modifying the is_dirty - * field of the cache info. - * - *------------------------------------------------------------------------- - */ -herr_t -H5SH_alloc(H5F_t *f, hid_t dxpl_id, haddr_t addr, hsize_t size, haddr_t *obj_addr_p) -{ - H5SH_t *sh = NULL; /* Segmented heap info */ - haddr_t free_addr; /* Address of free block */ - hsize_t free_len; /* Address of free block */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5SH_alloc, FAIL) - - /* - * Check arguments. - */ - HDassert(f); - - /* Look up the segmented heap */ - if (NULL == (sh = H5AC_protect(f, dxpl_id, H5AC_SGHP, addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load segmented heap info") - - /* Check for block of at least 'size' bytes in free list */ - free_addr = HADDR_UNDEF; - if (H5BT_locate(f, dxpl_id, sh->bt_free_addr, size, &free_addr, &free_len) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "error searching segmented heap free list") - - /* Check for finding large enough free block */ - if (H5F_addr_defined(free_addr)) { - /* Remove block from free list */ - if (H5BT_remove(f, dxpl_id, sh->bt_free_addr, free_addr, size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't remove block") - - /* Set address to return */ - *obj_addr_p = free_addr; - } /* end if */ - else { - H5SH_extend_t ex_info; - - /* Iterate over the existing heap blocks, to check for extending one */ - ex_info.f = f; - ex_info.dxpl_id = dxpl_id; - ex_info.file_mem_type = sh->file_mem_type; - ex_info.bt_free_addr = sh->bt_free_addr; - ex_info.max_extend_size = sh->max_extend_size; - ex_info.space_needed = size; - ex_info.loc = HADDR_UNDEF; - if(H5BT_iterate(f, dxpl_id, sh->bt_heap_addr, H5SH_alloc_extend_cb, &ex_info) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't iterate over heap blocks") - - /* Check if we managed to extend a heap block */ - if(H5F_addr_defined(ex_info.loc)) { - if(H5BT_insert(f, dxpl_id, sh->bt_heap_addr, ex_info.extend_addr, ex_info.extend_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't extend tracked block") - - /* Set address to return */ - *obj_addr_p = ex_info.loc; - } /* end if */ - else { - haddr_t block_addr; /* Address of new heap block */ - hsize_t block_size; /* Size of heap block */ - - /* Determine how large to make the heap block initially */ - if(size <= sh->min_size) - block_size = sh->min_size; - else - block_size = size; - - /* There's no internal or external space available, allocate a new heap block */ - if(HADDR_UNDEF == (block_addr = H5MF_alloc(f, sh->file_mem_type, dxpl_id, sh->min_size))) - HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "failed to allocate space for new heap block") - - /* Add heap block to tracker */ - if(H5BT_insert(f, dxpl_id, sh->bt_heap_addr, block_addr, block_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't insert heap block") - - /* Check if there is free space */ - if(size < sh->min_size) { - /* Add free space to tracker */ - if(H5BT_insert(f, dxpl_id, sh->bt_free_addr, block_addr + size, sh->min_size - size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't insert free space") - } /* end if */ - - /* Set address to return */ - *obj_addr_p = block_addr; - } /* end else */ - } /* end else */ - -done: - /* Release the block tracker info */ - if (sh && H5AC_unprotect(f, dxpl_id, H5AC_SGHP, addr, sh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release segmented heap info") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SH_alloc() */ - |