diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2007-03-11 23:15:03 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2007-03-11 23:15:03 (GMT) |
commit | e6b818134e24b1d4d99a612218e0a50ffa08bd28 (patch) | |
tree | 1f1e5b6b3bd58d92e395762ccfec6ffde5eaee0a /src/H5Orefcount.c | |
parent | 0b3cccd0cb2521ef77077d677581d2d3342cdc6f (diff) | |
download | hdf5-e6b818134e24b1d4d99a612218e0a50ffa08bd28.zip hdf5-e6b818134e24b1d4d99a612218e0a50ffa08bd28.tar.gz hdf5-e6b818134e24b1d4d99a612218e0a50ffa08bd28.tar.bz2 |
[svn-r13497] Description:
Move ref. count of # of links to an object out of the object header's
prefix and make it a header message instead (since it's a "rare" occurence),
eliminating some more space for each object in the file.
Inserting this "ref. count" message exposed a flaw in the library's
mechanism for locating a message to promote to another chunk and replace
with a continuation message, which required some additional work to fix.
It's still not completely robust, but it's working for more cases now and
detects failures robustly.
Reduced the minimum size of an object header chunk to just enough to
contain a header message prefix and continuation message.
Tested on:
FreeBSD/32 6.2 (duty)
Diffstat (limited to 'src/H5Orefcount.c')
-rw-r--r-- | src/H5Orefcount.c | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/src/H5Orefcount.c b/src/H5Orefcount.c new file mode 100644 index 0000000..8f49b8c --- /dev/null +++ b/src/H5Orefcount.c @@ -0,0 +1,324 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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: H5Orefcount.c + * Mar 10 2007 + * Quincey Koziol <koziol@hdfgroup.org> + * + * Purpose: Object ref. count messages. + * + *------------------------------------------------------------------------- + */ + +#define H5O_PACKAGE /*suppress error about including H5Opkg */ + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5Opkg.h" /* Object headers */ + + +/* PRIVATE PROTOTYPES */ +static void *H5O_refcount_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static herr_t H5O_refcount_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); +static void *H5O_refcount_copy(const void *_mesg, void *_dest); +static size_t H5O_refcount_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); +static herr_t H5O_refcount_free(void *_mesg); +static herr_t H5O_refcount_pre_copy_file(H5F_t *file_src, const void *mesg_src, + hbool_t *deleted, const H5O_copy_t *cpy_info, void *udata); +static herr_t H5O_refcount_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, + FILE * stream, int indent, int fwidth); + +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_REFCOUNT[1] = {{ + H5O_REFCOUNT_ID, /*message id number */ + "refcount", /*message name for debugging */ + sizeof(H5O_refcount_t), /*native message size */ + FALSE, /* messages are sharable? */ + H5O_refcount_decode, /*decode message */ + H5O_refcount_encode, /*encode message */ + H5O_refcount_copy, /*copy the native value */ + H5O_refcount_size, /*size of symbol table entry */ + NULL, /*default reset method */ + H5O_refcount_free, /* free method */ + NULL, /* file delete method */ + NULL, /* link method */ + NULL, /*set share method */ + NULL, /*can share method */ + H5O_refcount_pre_copy_file, /* pre copy native value to file */ + NULL, /* copy native value to file */ + NULL, /* post copy native value to file */ + NULL, /* get creation index */ + NULL, /* set creation index */ + H5O_refcount_debug /*debug the message */ +}}; + +/* Current version of ref. count information */ +#define H5O_REFCOUNT_VERSION 0 + +/* Declare a free list to manage the H5O_refcount_t struct */ +H5FL_DEFINE_STATIC(H5O_refcount_t); + + +/*------------------------------------------------------------------------- + * Function: H5O_refcount_decode + * + * Purpose: Decode a message and return a pointer to a newly allocated one. + * + * Return: Success: Ptr to new message in native form. + * Failure: NULL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 10 2007 + * + *------------------------------------------------------------------------- + */ +static void * +H5O_refcount_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, + const uint8_t *p) +{ + H5O_refcount_t *refcount = NULL; /* Reference count */ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_refcount_decode) + + /* check args */ + HDassert(f); + HDassert(p); + + /* Version of message */ + if(*p++ != H5O_REFCOUNT_VERSION) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message") + + /* Allocate space for message */ + if(NULL == (refcount = H5FL_MALLOC(H5O_refcount_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + /* Get ref. count for object */ + UINT32DECODE(p, *refcount) + + /* Set return value */ + ret_value = refcount; + +done: + if(ret_value == NULL && refcount != NULL) + H5FL_FREE(H5O_refcount_t, refcount); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_refcount_decode() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_refcount_encode + * + * Purpose: Encodes a message. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 10 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_refcount_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const void *_mesg) +{ + const H5O_refcount_t *refcount = (const H5O_refcount_t *)_mesg; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_refcount_encode) + + /* check args */ + HDassert(f); + HDassert(p); + HDassert(refcount); + + /* Message version */ + *p++ = H5O_REFCOUNT_VERSION; + + /* Object's ref. count */ + UINT32ENCODE(p, *refcount); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_refcount_encode() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_refcount_copy + * + * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if + * necessary. + * + * Return: Success: Ptr to _DEST + * Failure: NULL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 10 2007 + * + *------------------------------------------------------------------------- + */ +static void * +H5O_refcount_copy(const void *_mesg, void *_dest) +{ + const H5O_refcount_t *refcount = (const H5O_refcount_t *)_mesg; + H5O_refcount_t *dest = (H5O_refcount_t *) _dest; + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_refcount_copy) + + /* check args */ + HDassert(refcount); + if(!dest && NULL == (dest = H5FL_MALLOC(H5O_refcount_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + /* copy */ + *dest = *refcount; + + /* Set return value */ + ret_value = dest; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_refcount_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_refcount_size + * + * Purpose: Returns the size of the raw message in bytes not counting + * the message type or size fields, but only the data fields. + * This function doesn't take into account alignment. + * + * Return: Success: Message data size in bytes without alignment. + * Failure: zero + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 10 2007 + * + *------------------------------------------------------------------------- + */ +static size_t +H5O_refcount_size(const H5F_t *f, hbool_t UNUSED disable_shared, const void *_mesg) +{ + const H5O_refcount_t *refcount = (const H5O_refcount_t *)_mesg; + size_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_refcount_size) + + /* Set return value */ + ret_value = 1 /* Version */ + + 4; /* Ref. count */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_refcount_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_refcount_free + * + * Purpose: Free's the message + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, March 10, 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_refcount_free(void *mesg) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_refcount_free) + + HDassert(mesg); + + H5FL_FREE(H5O_refcount_t, mesg); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_refcount_free() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_refcount_pre_copy_file + * + * Purpose: Perform any necessary actions before copying message between + * files. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Saturday, March 10, 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_refcount_pre_copy_file(H5F_t UNUSED *file_src, const void UNUSED *native_src, + hbool_t *deleted, const H5O_copy_t *cpy_info, void UNUSED *udata) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_refcount_pre_copy_file) + + /* check args */ + HDassert(deleted); + HDassert(cpy_info); + + /* Always delete this message when copying objects between files. Let + * the copy routine set the correct ref. count. + */ + *deleted = TRUE; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_refcount_pre_copy_file() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_refcount_debug + * + * Purpose: Prints debugging info for a message. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 6 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_refcount_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * stream, + int indent, int fwidth) +{ + const H5O_refcount_t *refcount = (const H5O_refcount_t *) _mesg; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_refcount_debug) + + /* check args */ + HDassert(f); + HDassert(refcount); + HDassert(stream); + HDassert(indent >= 0); + HDassert(fwidth >= 0); + + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Number of links:", (unsigned)*refcount); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_refcount_debug() */ + |