summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5D.c187
-rw-r--r--src/H5Dprivate.h2
-rw-r--r--src/H5Dpublic.h1
-rw-r--r--src/H5Spoint.c12
-rw-r--r--src/H5Sselect.c2
-rw-r--r--src/H5TB.c101
-rw-r--r--src/H5Tprivate.h12
-rw-r--r--src/H5Tvlen.c1
8 files changed, 268 insertions, 50 deletions
diff --git a/src/H5D.c b/src/H5D.c
index cdb165a..49de18d 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -2662,8 +2662,10 @@ H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator_t op,
/* Check args */
if (NULL==op)
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid operator");
+#ifdef OLD_WAY
if (buf==NULL)
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer");
+#endif /* OLD_WAY */
if (H5I_DATATYPE != H5I_get_type(type_id))
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid datatype");
if (H5I_DATASPACE != H5I_get_type(space_id) ||
@@ -2724,6 +2726,191 @@ H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf)
FUNC_LEAVE(ret_value);
} /* end H5Dvlen_reclaim() */
+/*-------------------------------------------------------------------------
+ * Function: H5D_vlen_get_buf_size_alloc
+ *
+ * Purpose: This routine makes certain there is enough space in the temporary
+ * buffer for the new data to read in. All the VL data read in is actually
+ * placed in this buffer, overwriting the previous data. Needless to say,
+ * this data is not actually usable.
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, August 17, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *H5D_vlen_get_buf_size_alloc(size_t size, void *info)
+{
+ H5T_vlen_bufsize_t *vlen_bufsize=(H5T_vlen_bufsize_t *)info;
+ void *ret_value=NULL; /* Pointer to return */
+
+ FUNC_ENTER(H5D_vlen_get_buf_size_alloc, NULL);
+
+ /* Get a temporary pointer to space for the VL data */
+ if (H5TB_resize_buf(vlen_bufsize->vl_tbuf_id,size,&ret_value)>=0)
+ vlen_bufsize->size+=size;
+
+ FUNC_LEAVE(ret_value);
+} /* end H5D_vlen_get_buf_size_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_vlen_get_buf_size
+ *
+ * Purpose: This routine checks the number of bytes required to store a single
+ * element from a dataset in memory, creating a selection with just the
+ * single element selected to read in the element and using a custom memory
+ * allocator for any VL data encountered.
+ * The *size value is modified according to how many bytes are
+ * required to store the element in memory.
+ *
+ * Implementation: This routine actually performs the read with a custom
+ * memory manager which basically just counts the bytes requested and
+ * uses a temporary memory buffer (through the H5TB API) to make certain
+ * enough space is available to perform the read. Then the temporary
+ * buffer is released and the number of bytes allocated is returned.
+ * Kinda kludgy, but easier than the other method of trying to figure out
+ * the sizes without actually reading the data in... - QAK
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, August 17, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_vlen_get_buf_size(void UNUSED *elem, hid_t type_id, hsize_t UNUSED ndim, hssize_t *point, void *op_data)
+{
+ H5T_vlen_bufsize_t *vlen_bufsize=(H5T_vlen_bufsize_t *)op_data;
+ void *tbuf; /* pointer to temporary buffer */
+ H5T_t *dt = NULL;
+ herr_t ret_value=FAIL;
+
+ FUNC_ENTER(H5D_vlen_get_buf_size, FAIL);
+
+ assert(op_data);
+ assert(H5I_DATATYPE == H5I_get_type(type_id));
+
+ /* Check args */
+ if (NULL==(dt=H5I_object(type_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+
+ /* Make certain there is enough fixed-length buffer available */
+ if (H5TB_resize_buf(vlen_bufsize->fl_tbuf_id,H5T_get_size(dt),&tbuf)<0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't resize tbuf");
+
+ /* Select point to read in */
+ if (H5Sselect_elements(vlen_bufsize->space_id,H5S_SELECT_SET,1,(const hssize_t **)point)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't select point");
+
+ /* Read in the point (with the custom VL memory allocator) */
+ if(H5Dread(vlen_bufsize->dataset_id,type_id,H5S_ALL,vlen_bufsize->space_id,vlen_bufsize->xfer_pid,tbuf)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read point");
+
+ /* Set the correct return value, if we get this far */
+ ret_value=0;
+
+done:
+
+ FUNC_LEAVE(ret_value);
+} /* end H5D_vlen_get_buf_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dvlen_get_buf_size
+ *
+ * Purpose: This routine checks the number of bytes required to store the VL
+ * data from the dataset, using the space_id for the selection in the
+ * dataset on disk and the type_id for the memory representation of the
+ * VL data, in memory. The *size value is modified according to how many
+ * bytes are required to store the VL data in memory.
+ *
+ * Implementation: This routine actually performs the read with a custom
+ * memory manager which basically just counts the bytes requested and
+ * uses a temporary memory buffer (through the H5TB API) to make certain
+ * enough space is available to perform the read. Then the temporary
+ * buffer is released and the number of bytes allocated is returned.
+ * Kinda kludgy, but easier than the other method of trying to figure out
+ * the sizes without actually reading the data in... - QAK
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, August 11, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id,
+ hsize_t *size)
+{
+ H5T_vlen_bufsize_t vlen_bufsize={0};
+ char bogus; /* bogus value to pass to H5Diterate() */
+ herr_t ret_value=FAIL;
+
+ FUNC_ENTER(H5Dvlen_get_buf_size, FAIL);
+
+ /* Check args */
+ if (H5I_DATASET!=H5I_get_type(dataset_id) ||
+ H5I_DATATYPE!=H5I_get_type(type_id) ||
+ H5I_DATASPACE!=H5I_get_type(space_id) || size==NULL) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument");
+ }
+
+ /* Initialize the callback data block */
+ /* Save the dataset ID */
+ vlen_bufsize.dataset_id=dataset_id;
+
+ /* Get a copy of the dataspace ID */
+ if((vlen_bufsize.space_id=H5Dget_space(dataset_id))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy dataspace");
+
+ /* Grab the temporary buffers required */
+ if((vlen_bufsize.fl_tbuf_id=H5TB_get_buf(1,0,NULL))<0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available");
+ if((vlen_bufsize.vl_tbuf_id=H5TB_get_buf(1,0,NULL))<0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available");
+
+ /* Change to the custom memory allocation routines for reading VL data */
+ if((vlen_bufsize.xfer_pid=H5Pcreate(H5P_DATA_XFER))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "no dataset xfer plists available");
+
+ if(H5Pset_vlen_mem_manager(vlen_bufsize.xfer_pid,H5D_vlen_get_buf_size_alloc,&vlen_bufsize,NULL,NULL)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set VL data allocation routine");
+
+ /* Set the initial number of bytes required */
+ vlen_bufsize.size=0;
+
+ /* Call H5Diterate with args, etc. */
+ ret_value=H5Diterate(&bogus,type_id,space_id,H5D_vlen_get_buf_size,
+ &vlen_bufsize);
+
+ /* Get the size if we succeeded */
+ if(ret_value>=0)
+ *size=vlen_bufsize.size;
+
+done:
+ if(vlen_bufsize.space_id>0)
+ H5Sclose(vlen_bufsize.space_id);
+ if(vlen_bufsize.fl_tbuf_id>0)
+ H5TB_release_buf(vlen_bufsize.fl_tbuf_id);
+ if(vlen_bufsize.vl_tbuf_id>0)
+ H5TB_release_buf(vlen_bufsize.vl_tbuf_id);
+ if(vlen_bufsize.xfer_pid>0)
+ H5Pclose(vlen_bufsize.xfer_pid);
+
+ FUNC_LEAVE(ret_value);
+} /* end H5Dvlen_get_buf_size() */
+
/*-------------------------------------------------------------------------
* Function: H5Ddebug
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index ab289e6..7fabb66 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -74,5 +74,7 @@ __DLL__ H5S_t *H5D_get_space(H5D_t *dset);
__DLL__ H5D_t * H5D_open_oid(H5G_entry_t *ent);
__DLL__ H5F_t * H5D_get_file(const H5D_t *dset);
__DLL__ hsize_t H5D_get_storage_size(H5D_t *dset);
+__DLL__ void *H5D_vlen_get_buf_size_alloc(size_t size, void *info);
+__DLL__ herr_t H5D_vlen_get_buf_size(void *elem, hid_t type_id, hsize_t ndim, hssize_t *point, void *op_data);
#endif
diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h
index a0eddd1..1090a40 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -55,6 +55,7 @@ __DLL__ herr_t H5Dextend (hid_t dset_id, const hsize_t *size);
__DLL__ herr_t H5Diterate(void *buf, hid_t type_id, hid_t space_id,
H5D_operator_t op, void *operator_data);
__DLL__ herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf);
+__DLL__ herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *size);
__DLL__ herr_t H5Ddebug(hid_t dset_id, unsigned int flags);
#ifdef __cplusplus
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index a7062e9..3386275 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -816,11 +816,20 @@ H5S_point_select_valid (const H5S_t *space)
assert(space);
+#ifdef QAK
+printf("%s: check 1.0\n",FUNC);
+#endif /* QAK */
/* Check each point to determine whether selection+offset is within extent */
curr=space->select.sel_info.pnt_lst->head;
while(curr!=NULL) {
/* Check each dimension */
for(i=0; i<space->extent.u.simple.rank; i++) {
+#ifdef QAK
+printf("%s: check 2.0\n",FUNC);
+printf("%s: curr->pnt[%d]=%d\n",FUNC,(int)i,(int)curr->pnt[i]);
+printf("%s: space->select.offset[%d]=%d\n",FUNC,(int)i,(int)space->select.offset[i]);
+printf("%s: space->extent.u.simple.size[%d]=%d\n",FUNC,(int)i,(int)space->extent.u.simple.size[i]);
+#endif /* QAK */
/* Check if an offset has been defined */
/* Bounds check the selected point + offset against the extent */
if(((curr->pnt[i]+space->select.offset[i])>(hssize_t)space->extent.u.simple.size[i])
@@ -832,6 +841,9 @@ H5S_point_select_valid (const H5S_t *space)
curr=curr->next;
} /* end while */
+#ifdef QAK
+printf("%s: check 3.0\n",FUNC);
+#endif /* QAK */
FUNC_LEAVE (ret_value);
} /* end H5S_point_select_valid() */
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 556ae7e..fdf7dc4 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -519,7 +519,7 @@ herr_t H5S_select_elements (H5S_t *space, H5S_seloper_t op, size_t num_elem,
done:
FUNC_LEAVE (ret_value);
-} /* H5Sselect_elements() */
+} /* H5S_select_elements() */
/*--------------------------------------------------------------------------
NAME
diff --git a/src/H5TB.c b/src/H5TB.c
index 0396524..7712de8 100644
--- a/src/H5TB.c
+++ b/src/H5TB.c
@@ -377,59 +377,62 @@ H5TB_resize_buf(hid_t tbuf_id, hsize_t size, void **ptr)
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_realloc(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");
- }
+ /* Check if we actually need to re-size the buffer */
+ if(size > tbuf->size) {
+ /* Save old pointer for later */
+ old_ptr=tbuf->buf;
+
+ /* Try to resize buffer to new size */
+ if((tbuf->buf = H5MM_realloc(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;
+ /* 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 needs 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 */
- /*
- * Check if we need to move the buffer in the sorted list
- */
+ /* Find correct position in list */
+ curr=H5TB_list_head;
+ while(curr!=NULL) {
+ if(!curr->inuse && size<curr->size)
+ break;
+ curr=curr->next;
+ } /* end while */
- /* 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;
+ /* 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 */
-
- /* 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 */
+ } /* end if */
/* Assign the pointer to the buffer, if requested */
if(ptr!=NULL)
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index a870e0b..ca11e99 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -64,6 +64,18 @@ typedef enum {
} H5T_vlen_type_t;
/*
+ * Internal data structure for passing information to H5T_vlen_get_buf_size
+ */
+typedef struct {
+ hid_t dataset_id; /* ID of the dataset we are working on */
+ hid_t space_id; /* ID of the dataset's dataspace we are working on */
+ hid_t fl_tbuf_id; /* ID of the temporary buffer we are using for fixed-length data */
+ hid_t vl_tbuf_id; /* ID of the temporary buffer we are using for VL data */
+ hid_t xfer_pid; /* ID of the dataset xfer property list */
+ hsize_t size; /* Accumulated number of bytes for the selection */
+} H5T_vlen_bufsize_t;
+
+/*
* Is the path the special no-op path? The no-op function can be set by the
* application and there might be more than one no-op path in a
* multi-threaded application if one thread is using the no-op path when some
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c
index 446b1fb..ea341db 100644
--- a/src/H5Tvlen.c
+++ b/src/H5Tvlen.c
@@ -558,3 +558,4 @@ H5T_vlen_mark(H5T_t *dt, H5F_t *f, H5T_vlen_type_t loc)
done:
FUNC_LEAVE(ret_value);
} /* end H5T_vlen_mark() */
+