diff options
author | Robb Matzke <matzke@llnl.gov> | 1998-04-28 13:59:08 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1998-04-28 13:59:08 (GMT) |
commit | 66071d5078ad9841c8fbb430881ae2c6e059886e (patch) | |
tree | 163bf340ff1c2dcc9aebc35a1bea296a8da0e623 /src/H5Fsplit.c | |
parent | 4dcf59ae4461eec74a180d77783d9064d2aa3a58 (diff) | |
download | hdf5-66071d5078ad9841c8fbb430881ae2c6e059886e.zip hdf5-66071d5078ad9841c8fbb430881ae2c6e059886e.tar.gz hdf5-66071d5078ad9841c8fbb430881ae2c6e059886e.tar.bz2 |
[svn-r377] Changes since 19980424
----------------------
./src/H5A.c
./src/H5T.c
Fixed memory leaks. More to come later but PureAtria doesn't
make a Linux version of purify and the free version doesn't
compile with the new SMP Linux kernels so I had to debug over
the internet on a day that Sprint seemed to be having routing
problems... oh well. I got rid of most of the leaks.
./src/H5Apublic.h
Includes H5Ipublic.h for types in the header file.
./src/H5O.c
Comments improved for H5O_read()
./test/tattr.c
Removed a non-ANSI empty initializer.
./test/dsets.c
Include <string.h>
./test/istore.c
Fixed a non-ANSI pointer conversion.
Diffstat (limited to 'src/H5Fsplit.c')
-rw-r--r-- | src/H5Fsplit.c | 443 |
1 files changed, 443 insertions, 0 deletions
diff --git a/src/H5Fsplit.c b/src/H5Fsplit.c new file mode 100644 index 0000000..1359816 --- /dev/null +++ b/src/H5Fsplit.c @@ -0,0 +1,443 @@ +/* + * Copyright (C) 1997 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Thursday, November 13, 1997 + * + * Purpose: A driver that splits the meta data and raw data into two + * separate files. The high-order bit of the file address + * determines whether the address refers to the meta data file + * (high order bit is clear) or the raw data file (high order bit + * is set). + */ +#include <H5private.h> +#include <H5Eprivate.h> +#include <H5Fprivate.h> +#include <H5MFprivate.h> +#include <H5MMprivate.h> + +/* Default file name extensions */ +#define H5F_SPLIT_META_EXT ".meta" +#define H5F_SPLIT_RAW_EXT ".raw" + +#define PABLO_MASK H5F_split +static hbool_t interface_initialize_g = FALSE; +#define INTERFACE_INIT NULL + +static hbool_t H5F_split_access(const char *name, + const H5F_access_t *access_parms, int mode, + H5F_search_t *key/*out*/); +static H5F_low_t *H5F_split_open(const char *name, + const H5F_access_t *access_parms, uintn flags, + H5F_search_t *key/*out*/); +static herr_t H5F_split_close(H5F_low_t *lf, const H5F_access_t *access_parms); +static herr_t H5F_split_read(H5F_low_t *lf, const H5F_access_t *access_parms, + const haddr_t *addr, size_t size, + uint8 *buf/*out*/); +static herr_t H5F_split_write(H5F_low_t *lf, const H5F_access_t *access_parms, + const haddr_t *addr, size_t size, + const uint8 *buf); +static herr_t H5F_split_flush(H5F_low_t *lf, const H5F_access_t *access_parms); +static herr_t H5F_split_extend(H5F_low_t *lf, const H5F_access_t *access_parms, + intn op, hsize_t size, haddr_t *addr/*out*/); + +const H5F_low_class_t H5F_LOW_SPLIT_g[1] = {{ + H5F_split_access, /* access method */ + H5F_split_open, /* open method */ + H5F_split_close, /* close method */ + H5F_split_read, /* read method */ + H5F_split_write, /* write method */ + H5F_split_flush, /* flush method */ + H5F_split_extend, /* extend method */ +}}; + +/* + * This is the bit that determines whether the address is part of the meta + * data file or part of the raw data file. Eventually we'll want to pass + * this kind of thing down to this function from above... + */ +#define H5F_SPLIT_MASK 0x80000000 + + +/*------------------------------------------------------------------------- + * Function: H5F_split_open + * + * Purpose: Opens a split meta data/raw data family with the specified + * base name. The name of the meta data file will be created by + * appending `.h5' while the name of the raw data file will be + * created by appending `.raw'. + * + * Return: Success: Low-level file pointer + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Monday, November 13, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static H5F_low_t * +H5F_split_open(const char *name, const H5F_access_t *access_parms, + uintn flags, H5F_search_t *key/*out*/) +{ + H5F_low_t *lf = NULL, *ret_value = NULL; + char fullname[4096]; + const char *ext; /*file name extension*/ + const H5F_low_class_t *meta_type = NULL; + const H5F_low_class_t *raw_type = NULL; + + FUNC_ENTER(H5F_split_open, NULL); + + assert(name && *name); + assert (access_parms); + assert (H5F_LOW_SPLIT==access_parms->driver); + assert (access_parms->u.split.meta_access); + assert (access_parms->u.split.raw_access); + + /* Get member types */ + meta_type = H5F_low_class (access_parms->u.split.meta_access->driver); + raw_type = H5F_low_class (access_parms->u.split.raw_access->driver); + + /* Create the file descriptor */ + lf = H5MM_xcalloc(1, sizeof(H5F_low_t)); + lf->u.split.name = H5MM_xstrdup(name); + lf->u.split.mask = H5F_SPLIT_MASK; + + /* Open the meta data file */ + ext = access_parms->u.split.meta_ext ? + access_parms->u.split.meta_ext : H5F_SPLIT_META_EXT; + if (strlen (name)+strlen (ext) >= sizeof fullname) { + HGOTO_ERROR (H5E_IO, H5E_CANTINIT, NULL, "file name is too long"); + } + strcpy (fullname, name); + strcat (fullname, ext); + + lf->u.split.meta = H5F_low_open(meta_type, fullname, + access_parms->u.split.meta_access, + flags, key/*out*/); + if (NULL == lf->u.split.meta) { + HGOTO_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "can't open meta file"); + } + + /* Open the raw data file */ + ext = access_parms->u.split.raw_ext ? + access_parms->u.split.raw_ext : H5F_SPLIT_RAW_EXT; + if (strlen (name)+strlen (ext) >= sizeof fullname) { + HGOTO_ERROR (H5E_IO, H5E_CANTINIT, NULL, "file name is too long"); + } + strcpy (fullname, name); + strcat (fullname, ext); + + lf->u.split.raw = H5F_low_open(raw_type, fullname, + access_parms->u.split.raw_access, + flags, NULL); + if (NULL == lf->u.split.raw) { + HGOTO_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "can't open raw file"); + } + + /* Initialize the file size */ + H5F_low_size(lf->u.split.raw, &(lf->eof)); + lf->eof.offset |= lf->u.split.mask; + + HRETURN(lf); + + done: + if (!ret_value) { + if (lf) { + H5F_split_close(lf, access_parms); + H5MM_xfree(lf); + } + } + FUNC_LEAVE(ret_value); +} + +/*------------------------------------------------------------------------- + * Function: H5F_split_close + * + * Purpose: Closes a split file. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Monday, November 13, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_split_close(H5F_low_t *lf, const H5F_access_t *access_parms) +{ + FUNC_ENTER(H5F_split_close, FAIL); + + assert(lf); + + H5F_low_close(lf->u.split.meta, access_parms->u.split.meta_access); + H5F_low_close(lf->u.split.raw, access_parms->u.split.raw_access); + H5MM_xfree(lf->u.split.name); + + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5F_split_read + * + * Purpose: Reads a chunk of contiguous data from a split file. We + * assume that the data being read never crosses the meta + * data/raw data boundary. Reading past the end of a file + * returns zeros instead of failing. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Monday, November 13, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_split_read(H5F_low_t *lf, const H5F_access_t *access_parms, + const haddr_t *addr, size_t size, uint8 *buf/*out*/) +{ + haddr_t tmp_addr; + H5F_low_t *sub = NULL; + herr_t status; + const H5F_access_t *sub_parms = NULL; + + FUNC_ENTER(H5F_split_read, FAIL); + + assert(lf); + assert(addr && H5F_addr_defined(addr)); + assert(buf); + + /* Which file to we actually read from? */ + if (addr->offset & lf->u.split.mask) { + sub = lf->u.split.raw; + sub_parms = access_parms->u.split.raw_access; + tmp_addr.offset = addr->offset & (lf->u.split.mask - 1); + } else { + sub = lf->u.split.meta; + sub_parms = access_parms->u.split.meta_access; + tmp_addr = *addr; + } + + /* Read the data */ + status = H5F_low_read(sub, sub_parms, &tmp_addr, size, buf/*out*/); + FUNC_LEAVE(status); +} + + +/*------------------------------------------------------------------------- + * Function: H5F_split_write + * + * Purpose: Writes BUF to either the meta data file or the raw data file. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Monday, November 13, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_split_write(H5F_low_t *lf, const H5F_access_t *access_parms, + const haddr_t *addr, size_t size, const uint8 *buf) +{ + haddr_t tmp_addr; + H5F_low_t *sub = NULL; + herr_t status; + const H5F_access_t *sub_parms = NULL; + + FUNC_ENTER(H5F_split_write, FAIL); + + assert(lf); + assert(addr && H5F_addr_defined(addr)); + assert(buf); + + /* Which file to we actually write to? */ + if (addr->offset & lf->u.split.mask) { + sub = lf->u.split.raw; + sub_parms = access_parms->u.split.raw_access; + tmp_addr.offset = addr->offset & (lf->u.split.mask - 1); + } else { + sub = lf->u.split.meta; + sub_parms = access_parms->u.split.meta_access; + tmp_addr = *addr; + } + + /* Write the data */ + status = H5F_low_write(sub, sub_parms, &tmp_addr, size, buf); + FUNC_LEAVE(status); +} + +/*------------------------------------------------------------------------- + * Function: H5F_split_flush + * + * Purpose: Flushes all data to disk. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Monday, November 13, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_split_flush(H5F_low_t *lf, const H5F_access_t *access_parms) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER(H5F_split_flush, FAIL); + + assert(lf); + + ret_value = (H5F_low_flush(lf->u.split.meta, + access_parms->u.split.meta_access) >= 0 && + H5F_low_flush(lf->u.split.raw, + access_parms->u.split.raw_access) >= 0); + + FUNC_LEAVE(ret_value); +} + +/*------------------------------------------------------------------------- + * Function: H5F_split_access + * + * Purpose: Determines if both members of the split data file family can + * be accessed and returns the key for the first member of the + * family. + * + * Return: Success: TRUE or FALSE + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Monday, November 13, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +H5F_split_access(const char *name, const H5F_access_t *access_parms, + int mode, H5F_search_t *key/*out*/) +{ + char fullname[4096]; + hbool_t status; + const char *ext; /*file extension*/ + const H5F_low_class_t *meta_type = NULL; + const H5F_low_class_t *raw_type = NULL; + + FUNC_ENTER(H5F_split_access, FAIL); + + assert(name && *name); + assert (access_parms); + assert (H5F_LOW_SPLIT==access_parms->driver); + assert (access_parms->u.split.meta_access); + assert (access_parms->u.split.raw_access); + + /* The meta data member */ + meta_type = H5F_low_class (access_parms->u.split.meta_access->driver); + ext = access_parms->u.split.meta_ext ? + access_parms->u.split.meta_ext : H5F_SPLIT_META_EXT; + if (strlen (name)+strlen (ext) >= sizeof fullname) { + HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL, "file name is too long"); + } + strcpy (fullname, name); + strcat (fullname, ext); + + status = H5F_low_access(meta_type, fullname, + access_parms->u.split.meta_access, + mode, key/*out*/); + if (status < 0) { + HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, + "access call failed for meta data member"); + } + if (!status) HRETURN(FALSE); + + /* The raw data member */ + raw_type = H5F_low_class (access_parms->u.split.raw_access->driver); + ext = access_parms->u.split.raw_ext ? + access_parms->u.split.raw_ext : H5F_SPLIT_RAW_EXT; + if (strlen (name)+strlen (ext) >= sizeof fullname) { + HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL, "file name is too long"); + } + strcpy (fullname, name); + strcat (fullname, ext); + + status = H5F_low_access(raw_type, fullname, + access_parms->u.split.raw_access, + mode, NULL/*out*/); + if (status < 0) { + HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, + "access call failed for raw data member"); + } + FUNC_LEAVE(status); +} + +/*------------------------------------------------------------------------- + * Function: H5F_split_extend + * + * Purpose: Allocates memory from the end of the meta data file or raw + * data file. + * + * Return: Success: SUCCEED with the address of the allocated + * memory returned through the ADDR argument. + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, November 13, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_split_extend(H5F_low_t *lf, const H5F_access_t *access_parms, intn op, + hsize_t size, haddr_t *addr/*out*/) +{ + FUNC_ENTER(H5F_split_extend, FAIL); + + assert(lf); + assert(H5MF_META == op || H5MF_RAW == op); + assert(size > 0); + assert(addr); + + if (H5MF_META == op) { + if (H5F_low_extend(lf->u.split.meta, access_parms->u.split.meta_access, + op, size, addr/*out*/)<0) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "meta data allocation failed"); + } + if (addr->offset + size > lf->eof.offset) { + lf->eof.offset = addr->offset + size; + } + } else { + if (H5F_low_extend(lf->u.split.raw, access_parms->u.split.raw_access, + op, size, addr/*out*/)<0) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "raw data allocation failed"); + } + addr->offset |= lf->u.split.mask; + lf->eof = lf->u.split.raw->eof; + lf->eof.offset |= lf->u.split.mask; + } + + FUNC_LEAVE(SUCCEED); +} |