summaryrefslogtreecommitdiffstats
path: root/src/H5TB.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>1998-07-06 21:01:13 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>1998-07-06 21:01:13 (GMT)
commit43f13aeca28a722d6436d43dcd84a59918dc0950 (patch)
tree1ee94e4f1b64a7d027112d616d8617992c09520a /src/H5TB.c
parentd70e61b1dbd7ff16aa4ac5cad4a69bf87b84f208 (diff)
downloadhdf5-43f13aeca28a722d6436d43dcd84a59918dc0950.zip
hdf5-43f13aeca28a722d6436d43dcd84a59918dc0950.tar.gz
hdf5-43f13aeca28a722d6436d43dcd84a59918dc0950.tar.bz2
[svn-r451] Completely tore out existing dataspace API and replaced with code to match
API defined in the html/Dataspaces.html document. This code does not include support for strides, merging selections, or permutations of coordinates yet, but it's a drop-in replacement for the existing API with the same features.
Diffstat (limited to 'src/H5TB.c')
-rw-r--r--src/H5TB.c506
1 files changed, 506 insertions, 0 deletions
diff --git a/src/H5TB.c b/src/H5TB.c
new file mode 100644
index 0000000..627f755
--- /dev/null
+++ b/src/H5TB.c
@@ -0,0 +1,506 @@
+/****************************************************************************
+* NCSA HDF *
+* Software Development Group *
+* National Center for Supercomputing Applications *
+* University of Illinois at Urbana-Champaign *
+* 605 E. Springfield, Champaign IL 61820 *
+* *
+* For conditions of distribution and use, see the accompanying *
+* hdf/COPYING file. *
+* *
+****************************************************************************/
+
+/*
+ * Created: H5TB.c
+ * Jun 11 1998
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Temporary buffer management functions
+ *
+ * Library Public API Functions:
+ * H5TBget_buf - Get an ID for a temporary buffer
+ * H5TBbuf_ptr - Get a pointer to the temporary buffer's memory
+ * H5TBresize_buf - Resize a temporary buffer
+ * H5TBgarbage_coll- Free all unused temporary buffers
+ * H5TBrelease_buf - Release temporary buffer
+ *
+ * Modifications:
+ *
+ */
+
+#ifdef RCSID
+static char RcsId[] = "@(#)$Revision$";
+#endif
+
+/* $Id$ */
+
+#include <H5private.h> /* Generic Functions */
+#include <H5Iprivate.h> /* ID Functions */
+#include <H5Eprivate.h> /* Error handling */
+#include <H5MMprivate.h> /* Memory Management functions */
+#include <H5TBprivate.h> /* Temporary buffer info */
+
+/* Interface init/term information */
+#define PABLO_MASK H5TB_mask
+#define INTERFACE_INIT H5TB_init_interface
+static intn interface_initialize_g = FALSE;
+static herr_t H5TB_init_interface(void);
+static void H5TB_term_interface(void);
+
+/* Local information for managing buffers */
+#define H5TB_RESERVED_ATOMS 0
+
+typedef struct tag_H5TB_t {
+ hbool_t inuse; /* Flag to indicate whether the buffer is in use or not */
+ hsize_t size; /* Current size of the buffer */
+ struct tag_H5TB_t *next; /* Pointer to next buffer in list */
+ struct tag_H5TB_t *prev; /* Pointer to previous buffer in list */
+ void *buf; /* Pointer to actual temporary buffer */
+} H5TB_t;
+
+static H5TB_t * H5TB_list_head=NULL; /* pointer to beginning of temp. buffer list (list is in order of increasing size) */
+static H5TB_t * H5TB_list_tail=NULL; /* pointer to end of temp. buffer list */
+
+/* Local functions */
+herr_t H5TB_close(H5TB_t *tb);
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5TB_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5TB_init_interface()
+
+RETURNS
+ SUCCEED/FAIL
+DESCRIPTION
+ Initializes any interface-specific data or routines.
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5TB_init_interface(void)
+{
+ herr_t ret_value = SUCCEED;
+ FUNC_ENTER(H5TB_init_interface, FAIL);
+
+ /* Initialize the atom group for the file IDs */
+ if ((ret_value = H5I_init_group(H5_TEMPBUF, H5I_TEMPBUFID_HASHSIZE,
+ H5TB_RESERVED_ATOMS, NULL)) != FAIL) {
+ ret_value = H5_add_exit(&H5TB_term_interface);
+ }
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TB_term_interface
+ PURPOSE
+ Terminate various H5TB objects
+ USAGE
+ void H5TB_term_interface()
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ Release the atom group and any other resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static void
+H5TB_term_interface(void)
+{
+ /* Destroy the atom group */
+ /* Step through the list and free the buffers */
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5TB_close
+ *
+ * Purpose: Releases all memory associated with a temporary buffer.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, June 11, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5TB_close(H5TB_t *tb)
+{
+ FUNC_ENTER(H5TB_close, FAIL);
+
+ assert(tb);
+
+
+ /* Release the main structure */
+ H5MM_xfree(tb);
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TBget_buf
+ PURPOSE
+ Get an ID for a temporary buffer
+ USAGE
+ hid_t H5TBget_buf(size,resize)
+ hsize_t size; IN: Minimum size of buffer requested
+ hbool_t resize; IN: Whether to resize an existing buffer or get a
+ new buffer if one doesn't match the correct size
+ RETURNS
+ Valid buffer ID on success, negative on failure
+ DESCRIPTION
+ Checks for an available temporary buffer of at least the size requested and
+ returns an ID for an appropriate one. If a buffer of the minimum size
+ requested is not available and the resize flag is set, the smallest buffer
+ available is resized to be the correct size and returned, otherwise a new
+ buffer of the correct size is allocated and returned.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hid_t H5TBget_buf(hsize_t size, hbool_t resize)
+{
+ hid_t ret_value = FAIL;
+ H5TB_t *curr=H5TB_list_head, /* pointer to current temp. buffer */
+ *new; /* pointer to a newly created temp. buffer */
+
+ FUNC_ENTER (H5TBget_buf, FAIL);
+
+ while(curr!=NULL) {
+ if(!curr->inuse && size<curr->size)
+ break;
+ curr=curr->next;
+ } /* end while */
+
+ /* Check if we found a block or not */
+ if(curr!=NULL) {
+ curr->inuse=TRUE;
+ } else {
+ if(resize) {
+ curr=H5TB_list_head; /* start at beginning again */
+
+ /* Search for first node which isn't in use */
+ while(curr!=NULL) {
+ if(!curr->inuse)
+ break;
+ curr=curr->next;
+ } /* end while */
+
+ /* Mark the buffer in use and resize the buffer */
+ if(curr!=NULL) {
+ void * old_ptr=curr->buf;
+
+ if((curr->buf = H5MM_xrealloc(curr->buf, size))==NULL) {
+ curr->buf=old_ptr; /* restore pointer if no memory available */
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "unable to allocate space for temporary buffer");
+ }
+ curr->inuse=TRUE;
+ }
+ } /* end if */
+ } /* end else */
+
+ /* No blocks in the list are acceptable */
+ /* (either too small or not able to be resized) */
+ if(curr==NULL) {
+ if((new=H5MM_xcalloc(1,sizeof(H5TB_t)))==NULL)
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "unable to allocate space for temporary buffer struct");
+ new->inuse=TRUE;
+ new->size=size;
+ if((new->buf=H5MM_xmalloc(size))==NULL) {
+ H5MM_xfree(new); /* free structure */
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "unable to allocate space for temporary buffer");
+ }
+
+ /* Check if this is the first node in the list */
+ if(H5TB_list_head==NULL) {
+ H5TB_list_head=H5TB_list_tail=curr=new;
+ } else {
+ /* Find correct place to insert in list */
+ for(curr=H5TB_list_head; curr!=NULL; curr=curr->next) {
+ /* Found node to insert before */
+ if(curr->size > new->size) {
+ H5TB_t *tmp=curr->prev; /* temporary pointer */
+
+ /* Inserting at head of list */
+ if(tmp==NULL) {
+ H5TB_list_head=new;
+ new->next=curr;
+ curr->prev=new;
+ } else {
+ tmp->next=new;
+ new->prev=tmp;
+ curr->prev=new;
+ new->next=curr;
+ } /* end else */
+
+ /* set this so we can fall through to getting the ID */
+ curr=new;
+ } /* end if */
+ } /* end for */
+
+ /* Add to end of list */
+ if(curr==NULL) {
+ curr=H5TB_list_tail;
+ H5TB_list_tail=curr->next=new;
+ new->prev=curr;
+ } /* end if */
+
+ /* set this so we can fall through to getting the ID */
+ curr=new;
+ } /* end else */
+ } /* end if */
+
+ /* Atomize */
+ if ((ret_value=H5I_register (H5_TEMPBUF, curr))<0) {
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register temp. buffer atom");
+ }
+
+done:
+ if (ret_value < 0) {
+ }
+ FUNC_LEAVE(ret_value);
+} /* H5TBget_buf() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TBbuf_ptr
+ PURPOSE
+ Get the pointer to a temp. buffer memory
+ USAGE
+ void *H5TBbuf_ptr(tbid)
+ hid_t tbid; IN: Temp. buffer ID
+ RETURNS
+ Non-NULL pointer to buffer memory on success, NULL on failure
+ DESCRIPTION
+ Gets the pointer to a temp. buffer's memory.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+void *H5TBbuf_ptr(hid_t tbid)
+{
+ void *ret_value = NULL;
+ H5TB_t *tbuf; /* Pointer to temporary buffer */
+
+ FUNC_ENTER (H5TBbuf_ptr, NULL);
+
+ if (H5_TEMPBUF != H5I_group(tbid) ||
+ NULL == (tbuf = H5I_object(tbid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a temp. buffer");
+ }
+
+ ret_value=tbuf->buf;
+
+#ifdef LATER
+done:
+#endif
+ if (ret_value == NULL) {
+ }
+ FUNC_LEAVE(ret_value);
+} /* H5TBbuf_ptr() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TBresize_ptr
+ PURPOSE
+ Resize a temp. buffer to a new size
+ USAGE
+ herr_t H5TBresize_ptr(tbid, size)
+ hid_t tbid; IN: Temp. buffer ID to resize
+ hsize_t size; IN: New size of temp. buffer
+ RETURNS
+ non-negative on success, negative on failure
+ DESCRIPTION
+ Resizes a temporary buffer to a new size.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5TBresize_ptr(hid_t tbid, hsize_t size)
+{
+ herr_t ret_value = FAIL;
+ H5TB_t *tbuf, /* Pointer to temporary buffer */
+ *curr; /* Pointer to temp. buffer node */
+ void * old_ptr; /* Pointer to the previous buffer */
+
+ FUNC_ENTER (H5TBresize_ptr, FAIL);
+
+ if (H5_TEMPBUF != H5I_group(tbid) ||
+ NULL == (tbuf = H5I_object(tbid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a temp. buffer");
+ }
+
+ /* Save old pointer for later */
+ old_ptr=tbuf->buf;
+
+ /* Try to resize buffer to new size */
+ if((tbuf->buf = H5MM_xrealloc(tbuf->buf, size))==NULL) {
+ tbuf->buf=old_ptr; /* restore pointer if no memory available */
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "unable to allocate space for temporary buffer");
+ }
+
+ /* Change the size of the buffer */
+ tbuf->size=size;
+
+ /*
+ * Check if we need to move the buffer in the sorted list
+ */
+
+ /* Check if this is not the last node and it need's to move */
+ if(tbuf->next!=NULL && tbuf->next->size < tbuf->size) {
+ /* Remove this node from the list */
+ if(tbuf->prev==NULL) { /* remove from head of list */
+ H5TB_list_head=tbuf->next;
+ tbuf->next->prev=NULL;
+ } else { /* remove from middle of list */
+ tbuf->prev->next=tbuf->next;
+ tbuf->next->prev=tbuf->prev;
+ } /* end if */
+
+ /* Find correct position in list */
+ curr=H5TB_list_head;
+ while(curr!=NULL) {
+ if(!curr->inuse && size<curr->size)
+ break;
+ curr=curr->next;
+ } /* end while */
+
+ /* Insert into correct position in list */
+ if(curr!=NULL) { /* can't be adding to the beginning of list, so this is in the middle somewhere */
+ curr->prev->next=tbuf;
+ tbuf->prev=curr->prev;
+ curr->prev=tbuf;
+ tbuf->next=curr;
+ } else { /* append to end of list */
+ H5TB_list_tail->next=tbuf;
+ tbuf->prev=H5TB_list_tail;
+ tbuf->next=NULL;
+ H5TB_list_tail=tbuf;
+ } /* end else */
+ } /* end if */
+
+#ifdef LATER
+done:
+#endif
+ if (ret_value == FAIL) {
+ }
+ FUNC_LEAVE(ret_value);
+} /* H5TBresize_ptr() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TBgarbage_coll
+ PURPOSE
+ Release all unused temporary buffers
+ USAGE
+ herr_t H5TBgarbase_coll()
+ RETURNS
+ non-negative on success, negative on failure
+ DESCRIPTION
+ Steps through the list of temporary buffers, removing unused nodes from the
+ list and freeing their memory
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5TBgarbage_coll(void)
+{
+ herr_t ret_value = FAIL;
+ H5TB_t *curr,*next; /* Current temp. buffer node */
+
+ FUNC_ENTER (H5TBgarbage_coll, FAIL);
+
+ /* Step through the list, remove each unused node, repair the list and free the node */
+ curr=H5TB_list_head;
+ while(curr!=NULL) {
+ next=curr->next;
+ if(!curr->inuse) {
+ /* maintain list head & tail */
+ if(H5TB_list_head==curr)
+ H5TB_list_head=curr->next;
+ if(H5TB_list_tail==curr)
+ H5TB_list_tail=curr->prev;
+
+ /* Delete node from list */
+ if(curr->prev!=NULL)
+ curr->prev->next=curr->next;
+ if(curr->next!=NULL)
+ curr->next->prev=curr->prev;
+
+ /* Free memory for node */
+ if(curr->buf!=NULL)
+ H5MM_xfree(curr->buf);
+ H5MM_xfree(curr);
+ } /* end if */
+ curr=next;
+ } /* end while */
+
+ ret_value=SUCCEED;
+
+#ifdef LATER
+done:
+#endif
+ if (ret_value == FAIL) {
+ }
+ FUNC_LEAVE(ret_value);
+} /* H5TBgarbage_coll() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TBrelease_buf
+ PURPOSE
+ Release a temp. buffer back to the list of unused ones.
+ USAGE
+ herr_t H5TBrelease_buf(tbid)
+ hid_t tbid; IN: Temp. buffer ID to release
+ RETURNS
+ non-negative on success, negative on failure
+ DESCRIPTION
+ Releases a temporary buffer.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5TBrelease_buf(hid_t tbid)
+{
+ herr_t ret_value = FAIL;
+ H5TB_t *tbuf; /* Pointer to temporary buffer */
+
+ FUNC_ENTER (H5TBresize_ptr, FAIL);
+
+ if (H5_TEMPBUF != H5I_group(tbid) ||
+ NULL == (tbuf = H5I_object(tbid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a temp. buffer");
+ }
+
+ /* Release the buffer */
+ tbuf->inuse=FALSE;
+
+ ret_value=SUCCEED;
+
+#ifdef LATER
+done:
+#endif
+ if (ret_value == FAIL) {
+ }
+ FUNC_LEAVE(ret_value);
+} /* H5TBresize_ptr() */
+