diff options
Diffstat (limited to 'src/H5Ochunk.c')
-rw-r--r-- | src/H5Ochunk.c | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/src/H5Ochunk.c b/src/H5Ochunk.c new file mode 100644 index 0000000..59102b6 --- /dev/null +++ b/src/H5Ochunk.c @@ -0,0 +1,359 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5Ochunk.c + * Jul 13 2008 + * Quincey Koziol <koziol@hdfgroup.org> + * + * Purpose: Object header chunk routines. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5O_PACKAGE /*suppress error about including H5Opkg */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Opkg.h" /* Object headers */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + +/* Declare the free list for H5O_chunk_proxy_t's */ +H5FL_DEFINE(H5O_chunk_proxy_t); + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_add + * + * Purpose: Add new chunk for object header to metadata cache + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 13 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx) +{ + H5O_chunk_proxy_t *chk_proxy = NULL; /* Proxy for chunk, to mark it dirty in the cache */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_chunk_add, FAIL) + + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(idx < oh->nchunks); + HDassert(idx > 0); + + /* Allocate space for the object header data structure */ + if(NULL == (chk_proxy = H5FL_CALLOC(H5O_chunk_proxy_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Set the values in the chunk proxy */ + chk_proxy->oh = oh; + chk_proxy->chunkno = idx; + + /* Insert the chunk proxy into the cache */ + if(H5AC_set(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, chk_proxy, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header chunk") + chk_proxy = NULL; + + /* Increment reference count on object header */ + if(H5O_inc_rc(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, FAIL, "can't increment reference count on object header") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_chunk_add() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_protect + * + * Purpose: Protect an object header chunk for modifications + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 17 2008 + * + *------------------------------------------------------------------------- + */ +H5O_chunk_proxy_t * +H5O_chunk_protect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx) +{ + H5O_chunk_proxy_t *chk_proxy; /* Proxy for protected chunk */ + H5O_chunk_proxy_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_chunk_protect, NULL) + + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(idx < oh->nchunks); + + /* Check for protecting first chunk */ + if(0 == idx) { + /* Create new "fake" chunk proxy for first chunk */ + /* (since the first chunk is already handled by the H5O_t object) */ + if(NULL == (chk_proxy = H5FL_CALLOC(H5O_chunk_proxy_t))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "memory allocation failed") + + /* Set chunk proxy fields */ + chk_proxy->oh = oh; + chk_proxy->chunkno = idx; + } /* end if */ + else { + H5O_chk_cache_ud_t chk_udata; /* User data for loading chunk */ + + /* Construct the user data for protecting chunk proxy */ + /* (and _not_ decoding it) */ + HDmemset(&chk_udata, 0, sizeof(chk_udata)); + chk_udata.oh = oh; + chk_udata.chunkno = idx; + chk_udata.chunk_size = oh->chunk[idx].size; + + /* Get the chunk proxy */ + if(NULL == (chk_proxy = (H5O_chunk_proxy_t *)H5AC_protect(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, NULL, &chk_udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header chunk") + + /* Sanity check */ + HDassert(chk_proxy->oh == oh); + HDassert(chk_proxy->chunkno == idx); + } /* end else */ + + /* Set return value */ + ret_value = chk_proxy; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_chunk_protect() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_unprotect + * + * Purpose: Unprotect an object header chunk after modifications + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 17 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_chunk_unprotect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_chunk_proxy_t *chk_proxy, + unsigned chk_flags) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_chunk_unprotect, FAIL) + + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(chk_proxy); + HDassert(!(chk_flags & (unsigned)~(H5AC__DIRTIED_FLAG | H5AC__SIZE_CHANGED_FLAG))); + + /* Check for releasing first chunk */ + if(0 == chk_proxy->chunkno) { + /* Check for resizing the first chunk */ + if(chk_flags & H5AC__SIZE_CHANGED_FLAG) { + /* Resize object header in cache */ + if(H5AC_resize_pinned_entry(oh, oh->chunk[0].size) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRESIZE, FAIL, "unable to resize chunk in cache") + } /* end if */ + /* Check for dirtying the first chunk */ + else if(chk_flags & H5AC__DIRTIED_FLAG) { + /* Mark object header as dirty in cache */ + if(H5AC_mark_pinned_or_protected_entry_dirty(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, FAIL, "unable to mark object header as dirty") + } /* end else/if */ + else { + /* Sanity check */ + HDassert(0 && "Unknown chunk proxy flag(s)?!?"); + } /* end else */ + + /* Free fake chunk proxy */ + chk_proxy = H5FL_FREE(H5O_chunk_proxy_t, chk_proxy); + } /* end if */ + else { + /* Release the chunk proxy from the cache, marking it dirty */ + if(H5AC_unprotect(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[chk_proxy->chunkno].addr, chk_proxy, chk_flags) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header chunk") + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_chunk_unprotect() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_update_idx + * + * Purpose: Update the chunk index for a chunk proxy + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 13 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_chunk_update_idx(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx) +{ + H5O_chunk_proxy_t *chk_proxy; /* Proxy for chunk, to mark it dirty in the cache */ + H5O_chk_cache_ud_t chk_udata; /* User data for loading chunk */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_chunk_update_idx, FAIL) + + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(idx < oh->nchunks); + HDassert(idx > 0); + + /* Construct the user data for protecting chunk proxy */ + /* (and _not_ decoding it) */ + HDmemset(&chk_udata, 0, sizeof(chk_udata)); + chk_udata.oh = oh; + chk_udata.chunkno = idx; + chk_udata.chunk_size = oh->chunk[idx].size; + + /* Get the chunk proxy */ + if(NULL == (chk_proxy = (H5O_chunk_proxy_t *)H5AC_protect(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, NULL, &chk_udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + + /* Update index for chunk proxy in cache */ + chk_proxy->chunkno = idx; + + /* Release the chunk proxy from the cache, marking it deleted */ + if(H5AC_unprotect(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, chk_proxy, H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header chunk") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_chunk_update_idx() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_delete + * + * Purpose: Notify metadata cache that a chunk has been deleted + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 13 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx) +{ + H5O_chunk_proxy_t *chk_proxy; /* Proxy for chunk, to mark it dirty in the cache */ + H5O_chk_cache_ud_t chk_udata; /* User data for loading chunk */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_chunk_delete, FAIL) + + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(idx < oh->nchunks); + HDassert(idx > 0); + + /* Construct the user data for protecting chunk proxy */ + /* (and _not_ decoding it) */ + HDmemset(&chk_udata, 0, sizeof(chk_udata)); + chk_udata.oh = oh; + chk_udata.chunkno = idx; + chk_udata.chunk_size = oh->chunk[idx].size; + + /* Get the chunk proxy */ + if(NULL == (chk_proxy = (H5O_chunk_proxy_t *)H5AC_protect(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, NULL, &chk_udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + + /* Sanity check */ + HDassert(chk_proxy->oh == oh); + HDassert(chk_proxy->chunkno == idx); + + /* Release the chunk proxy from the cache, marking it deleted */ + if(H5AC_unprotect(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, chk_proxy, (H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header chunk") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_chunk_delete() */ + |