diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2000-04-04 21:00:31 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2000-04-04 21:00:31 (GMT) |
commit | 02e4ee5edf5d1c8fe285497def5cd7b7afbf77e4 (patch) | |
tree | 4b36327c0da85d62ea116da32d0f114700d0f6c9 /src/H5Shyper.c | |
parent | 7170bbbc96f2b29f42be53f8271fc359f617e09c (diff) | |
download | hdf5-02e4ee5edf5d1c8fe285497def5cd7b7afbf77e4.zip hdf5-02e4ee5edf5d1c8fe285497def5cd7b7afbf77e4.tar.gz hdf5-02e4ee5edf5d1c8fe285497def5cd7b7afbf77e4.tar.bz2 |
[svn-r2073] Added free-list code to the library and took out the older "temporary buffer"
code, since the functionality was superceded. See the followup document for
details on the free-list code.
Diffstat (limited to 'src/H5Shyper.c')
-rw-r--r-- | src/H5Shyper.c | 566 |
1 files changed, 438 insertions, 128 deletions
diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 5be59dc..554f59c 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -10,11 +10,11 @@ #include <H5private.h> #include <H5Dprivate.h> #include <H5Eprivate.h> +#include <H5FLprivate.h> /*Free Lists */ #include <H5Iprivate.h> #include <H5MMprivate.h> #include <H5Pprivate.h> #include <H5Sprivate.h> -#include <H5TBprivate.h> #include <H5Vprivate.h> /* Interface initialization */ @@ -62,9 +62,8 @@ typedef struct { /* Static function prototypes */ static intn H5S_hyper_bsearch(hssize_t size, H5S_hyper_bound_t *barr, size_t count); -static hid_t -H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, - H5S_hyper_bound_t **lo_bounds, +static H5S_hyper_region_t * H5S_hyper_get_regions (size_t *num_regions, + intn dim, size_t bound_count, H5S_hyper_bound_t **lo_bounds, H5S_hyper_bound_t **hi_bounds, hssize_t *pos, hssize_t *offset); static size_t H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info); @@ -117,6 +116,31 @@ const H5S_mconv_t H5S_HYPER_MCONV[1] = {{ /* Array for use with I/O algorithms which frequently need array of zeros */ static const hssize_t zero[H5O_LAYOUT_NDIMS]={0}; /* Array of zeros */ +/* Declare a free list to manage the H5S_hyper_node_t struct */ +H5FL_DEFINE_STATIC(H5S_hyper_node_t); + +/* Declare a free list to manage the H5S_hyper_list_t struct */ +H5FL_DEFINE_STATIC(H5S_hyper_list_t); + +/* Declare a free list to manage arrays of hsize_t */ +H5FL_ARR_DEFINE_STATIC(hsize_t,H5S_MAX_RANK); + +typedef H5S_hyper_bound_t *H5S_hyper_bound_ptr_t; +/* Declare a free list to manage arrays of H5S_hyper_bound_ptr_t */ +H5FL_ARR_DEFINE_STATIC(H5S_hyper_bound_ptr_t,H5S_MAX_RANK); + +/* Declare a free list to manage arrays of H5S_hyper_dim_t */ +H5FL_ARR_DEFINE_STATIC(H5S_hyper_dim_t,H5S_MAX_RANK); + +/* Declare a free list to manage arrays of H5S_hyper_bound_t */ +H5FL_ARR_DEFINE_STATIC(H5S_hyper_bound_t,-1); + +/* Declare a free list to manage arrays of H5S_hyper_region_t */ +H5FL_ARR_DEFINE_STATIC(H5S_hyper_region_t,-1); + +/* Declare a free list to manage blocks of hyperslab data */ +H5FL_BLK_DEFINE_STATIC(hyper_block); + /*------------------------------------------------------------------------- * Function: H5S_hyper_init @@ -147,7 +171,7 @@ H5S_hyper_init (const struct H5O_layout_t UNUSED *layout, sel_iter->hyp.elmt_left=space->select.num_elem; /* Allocate the position & initialize to invalid location */ - sel_iter->hyp.pos = H5MM_malloc(space->extent.u.simple.rank * sizeof(hssize_t)); + sel_iter->hyp.pos = H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0); sel_iter->hyp.pos[0]=(-1); H5V_array_fill(sel_iter->hyp.pos, sel_iter->hyp.pos, sizeof(hssize_t), space->extent.u.simple.rank); @@ -229,12 +253,12 @@ H5S_hyper_compare_regions (const void *r1, const void *r2) * *------------------------------------------------------------------------- */ -static hid_t +static H5S_hyper_region_t * H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, H5S_hyper_bound_t **lo_bounds, H5S_hyper_bound_t **hi_bounds, hssize_t *pos, hssize_t *offset) { - hid_t ret_value=FAIL; /* Id of temporary buffer to return */ + H5S_hyper_region_t *ret_value=NULL; /* Pointer to array of regions to return */ H5S_hyper_region_t *reg=NULL; /* Pointer to array of regions */ H5S_hyper_node_t *node; /* Region node for a given boundary */ size_t num_reg=0; /* Number of regions in array */ @@ -244,7 +268,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, intn temp_dim; /* Temporary dim. holder */ size_t i; /* Counters */ - FUNC_ENTER (H5S_hyper_get_regions, FAIL); + FUNC_ENTER (H5S_hyper_get_regions, NULL); assert(num_regions); assert(lo_bounds); @@ -271,7 +295,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, /* Check if we've allocated the array yet */ if(num_reg==0) { /* Allocate temporary buffer */ - ret_value=H5TB_get_buf(sizeof(H5S_hyper_region_t),0,(void **)®); + reg=H5FL_ARR_ALLOC(H5S_hyper_region_t,1,0); /* Initialize with first region */ reg[0].start=MAX(lo_bounds[0][i].bound,pos[0])+offset[0]; @@ -294,7 +318,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, hi_bounds[0][i].bound!=reg[curr_reg].end) { /* Enlarge array */ - H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),(void **)®); + reg=H5FL_ARR_REALLOC(H5S_hyper_region_t,reg,num_reg+1); /* Initialize with new region */ reg[num_reg].start=lo_bounds[0][i].bound+offset[0]; @@ -360,7 +384,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, printf("%s: check 3.1\n", FUNC); #endif /* QAK */ /* Allocate temporary buffer */ - ret_value=H5TB_get_buf(sizeof(H5S_hyper_region_t),0,(void **)®); + reg=H5FL_ARR_ALLOC(H5S_hyper_region_t,1,0); /* Initialize with first region */ reg[0].start=MAX(node->start[next_dim],pos[next_dim])+offset[next_dim]; @@ -387,7 +411,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, (int)reg[curr_reg].end); #endif /* QAK */ /* Enlarge array */ - H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),(void **)®); + reg=H5FL_ARR_REALLOC(H5S_hyper_region_t,reg,num_reg+1); /* Initialize with new region */ reg[num_reg].start=node->start[next_dim]+offset[next_dim]; @@ -421,6 +445,9 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, /* Save the number of regions we generated */ *num_regions=num_reg; + /* Set return value */ + ret_value=reg; + #ifdef QAK printf("%s: check 10.0, reg=%p, num_reg=%d\n", FUNC,reg,num_reg); @@ -460,7 +487,7 @@ H5S_hyper_block_cache (H5S_hyper_node_t *node, assert(io_info); /* Allocate temporary buffer of proper size */ - if((node->cinfo.block_id=H5TB_get_buf(node->cinfo.size*io_info->elmt_size,1,(void **)&(node->cinfo.block)))<0) + if((node->cinfo.block=H5FL_BLK_ALLOC(hyper_block,node->cinfo.size*io_info->elmt_size,0))==NULL) HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab cache block"); @@ -534,7 +561,7 @@ H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_io_info_t *io_info, hsiz /* If we've read in all the elements from the block, throw it away */ if(node->cinfo.rleft==0 && (node->cinfo.wleft==0 || node->cinfo.wleft==node->cinfo.size)) { /* Release the temporary buffer */ - H5TB_release_buf(node->cinfo.block_id); + H5FL_BLK_FREE(hyper_block,node->cinfo.block); /* Reset the caching flag for next time */ node->cinfo.cached=0; @@ -603,7 +630,7 @@ H5S_hyper_block_write (H5S_hyper_node_t *node, HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); /* Release the temporary buffer */ - H5TB_release_buf(node->cinfo.block_id); + H5FL_BLK_FREE(hyper_block,node->cinfo.block); /* Reset the caching flag for next time */ node->cinfo.cached=0; @@ -634,7 +661,6 @@ H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info) { hsize_t region_size; /* Size of lowest region */ uintn parm_init=0; /* Whether one-shot parameters set up */ - hid_t reg_id; /* ID of temporary region buffer */ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */ size_t num_regions; /* number of regions overlapped */ size_t i; /* Counters */ @@ -658,15 +684,12 @@ H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info) /* Get a sorted list (in the next dimension down) of the regions which */ /* overlap the current index in this dim */ - if((reg_id=H5S_hyper_get_regions(&num_regions,dim, + if((regions=H5S_hyper_get_regions(&num_regions,dim, io_info->space->select.sel_info.hslab.hyper_lst->count, io_info->lo_bounds, io_info->hi_bounds, - io_info->iter->hyp.pos,io_info->space->select.offset))>=0) { + io_info->iter->hyp.pos,io_info->space->select.offset))!=NULL) { - /* Get the pointer to the actual regions array */ - regions=H5TB_buf_ptr(reg_id); - - /* + /* * Check if this is the second to last dimension in dataset (Which * means that we've got a list of the regions in the fastest changing * dimension and should input those regions). @@ -790,7 +813,7 @@ H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info) } /* end else */ /* Release the temporary buffer */ - H5TB_release_buf(reg_id); + H5FL_ARR_FREE(H5S_hyper_region_t,regions); } /* end if */ FUNC_LEAVE (num_read); @@ -829,11 +852,12 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, hid_t dxpl_id, void *_buf/*out*/) { - H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */ - H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */ + H5S_hyper_bound_t **lo_bounds=NULL; /* Lower (closest to the origin) bound array for each dimension */ + H5S_hyper_bound_t **hi_bounds=NULL; /* Upper (farthest from the origin) bound array for each dimension */ H5S_hyper_io_info_t io_info; /* Block of parameters to pass into recursive calls */ intn i; /*counters */ - size_t num_read; /* number of elements read into buffer */ + size_t num_read=0; /* number of elements read into buffer */ + herr_t ret_value=SUCCEED; FUNC_ENTER (H5S_hyper_fgath, 0); @@ -850,10 +874,10 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, printf("%s: check 1.0\n", FUNC); #endif /* QAK */ /* Allocate space for the low & high bound arrays */ - lo_bounds = H5MM_malloc(file_space->extent.u.simple.rank * - sizeof(H5S_hyper_bound_t *)); - hi_bounds = H5MM_malloc(file_space->extent.u.simple.rank * - sizeof(H5S_hyper_bound_t *)); + if((lo_bounds=H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,file_space->extent.u.simple.rank,0))==NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); + if((hi_bounds=H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,file_space->extent.u.simple.rank,0))==NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); /* Initialize to correct order to walk through arrays. (When another iteration order besides the default 'C' order is chosen, @@ -896,12 +920,16 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, printf("%s: check 5.0, num_read=%d\n",FUNC,(int)num_read); #endif /* QAK */ +done: /* Release the memory we allocated */ - H5MM_xfree(lo_bounds); - H5MM_xfree(hi_bounds); + if (lo_bounds) + H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,lo_bounds); + if (hi_bounds) + H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,hi_bounds); - FUNC_LEAVE (num_read); + FUNC_LEAVE (ret_value==SUCCEED ? num_read : 0); } /* H5S_hyper_fgath() */ + /*------------------------------------------------------------------------- * Function: H5S_hyper_fwrite @@ -925,7 +953,6 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info) { hsize_t region_size; /* Size of lowest region */ uintn parm_init=0; /* Whether one-shot parameters set up */ - hid_t reg_id; /* ID of temporary region buffer */ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */ size_t num_regions; /* number of regions overlapped */ size_t i; /* Counters */ @@ -948,13 +975,11 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info) #endif /* QAK */ /* Get a sorted list (in the next dimension down) of the regions which */ /* overlap the current index in this dim */ - if((reg_id=H5S_hyper_get_regions(&num_regions,dim, + if((regions=H5S_hyper_get_regions(&num_regions,dim, io_info->space->select.sel_info.hslab.hyper_lst->count, io_info->lo_bounds, io_info->hi_bounds, - io_info->iter->hyp.pos,io_info->space->select.offset))>=0) { + io_info->iter->hyp.pos,io_info->space->select.offset))!=NULL) { - /* Get the pointer to the actual regions array */ - regions=H5TB_buf_ptr(reg_id); #ifdef QAK printf("%s: check 1.1, regions=%p\n", FUNC,regions); printf("%s: check 1.2, rank=%d\n", @@ -1056,7 +1081,7 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info) } /* end else */ /* Release the temporary buffer */ - H5TB_release_buf(reg_id); + H5FL_ARR_FREE(H5S_hyper_region_t,regions); } /* end if */ #ifdef QAK @@ -1093,11 +1118,12 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, hid_t dxpl_id, const void *_buf) { - H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */ - H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */ + H5S_hyper_bound_t **lo_bounds=NULL; /* Lower (closest to the origin) bound array for each dimension */ + H5S_hyper_bound_t **hi_bounds=NULL; /* Upper (farthest from the origin) bound array for each dimension */ H5S_hyper_io_info_t io_info; /* Block of parameters to pass into recursive calls */ intn i; /*counters */ - size_t num_written; /* number of elements read into buffer */ + size_t num_written=0; /* number of elements read into buffer */ + herr_t ret_value=SUCCEED; FUNC_ENTER (H5S_hyper_fscat, 0); @@ -1114,10 +1140,11 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout, printf("%s: check 1.0\n", FUNC); #endif /* QAK */ /* Allocate space for the low & high bound arrays */ - lo_bounds = H5MM_malloc(file_space->extent.u.simple.rank * - sizeof(H5S_hyper_bound_t *)); - hi_bounds = H5MM_malloc(file_space->extent.u.simple.rank * - sizeof(H5S_hyper_bound_t *)); + if((lo_bounds=H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,file_space->extent.u.simple.rank,0))==NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for low bounds"); + + if((hi_bounds=H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,file_space->extent.u.simple.rank,0))==NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for high bounds"); /* * Initialize to correct order to walk through arrays. (When another @@ -1155,15 +1182,19 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout, /* starting with the slowest changing dimension */ num_written=H5S_hyper_fwrite(-1,&io_info); - /* Release the memory we allocated */ - H5MM_xfree(lo_bounds); - H5MM_xfree(hi_bounds); +done: + /* Release the memory we allocated back to the free list*/ + if (lo_bounds) + H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,lo_bounds); + if (hi_bounds) + H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,hi_bounds); #ifdef QAK printf("%s: check 2.0\n", FUNC); #endif /* QAK */ - FUNC_LEAVE (num_written >0 ? SUCCEED : FAIL); + FUNC_LEAVE (ret_value==FAIL ? ret_value : (num_written >0) ? SUCCEED : FAIL); } /* H5S_hyper_fscat() */ + /*------------------------------------------------------------------------- * Function: H5S_hyper_mread @@ -1186,7 +1217,6 @@ static size_t H5S_hyper_mread (intn dim, H5S_hyper_io_info_t *io_info) { hsize_t region_size; /* Size of lowest region */ - hid_t reg_id; /* ID of temporary region buffer */ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */ size_t num_regions; /* number of regions overlapped */ size_t i; /* Counters */ @@ -1203,13 +1233,10 @@ H5S_hyper_mread (intn dim, H5S_hyper_io_info_t *io_info) /* Get a sorted list (in the next dimension down) of the regions which */ /* overlap the current index in this dim */ - if((reg_id=H5S_hyper_get_regions(&num_regions,dim, + if((regions=H5S_hyper_get_regions(&num_regions,dim, io_info->space->select.sel_info.hslab.hyper_lst->count, io_info->lo_bounds, io_info->hi_bounds, - io_info->iter->hyp.pos,io_info->space->select.offset))>=0) { - - /* Get the pointer to the actual regions array */ - regions=H5TB_buf_ptr(reg_id); + io_info->iter->hyp.pos,io_info->space->select.offset))!=NULL) { /* Check if this is the second to last dimension in dataset */ /* (Which means that we've got a list of the regions in the fastest */ @@ -1303,11 +1330,12 @@ H5S_hyper_mread (intn dim, H5S_hyper_io_info_t *io_info) } /* end else */ /* Release the temporary buffer */ - H5TB_release_buf(reg_id); + H5FL_ARR_FREE(H5S_hyper_region_t,regions); } /* end if */ FUNC_LEAVE (num_read); } /* H5S_hyper_mread() */ + /*------------------------------------------------------------------------- * Function: H5S_hyper_mgath @@ -1366,10 +1394,8 @@ H5S_hyper_mgath (const void *_buf, size_t elmt_size, #endif /* QAK */ /* Allocate space for the low & high bound arrays */ - lo_bounds = H5MM_malloc(mem_space->extent.u.simple.rank * - sizeof(H5S_hyper_bound_t *)); - hi_bounds = H5MM_malloc(mem_space->extent.u.simple.rank * - sizeof(H5S_hyper_bound_t *)); + lo_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,mem_space->extent.u.simple.rank,0); + hi_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,mem_space->extent.u.simple.rank,0); /* * Initialize to correct order to walk through arrays. (When another @@ -1423,8 +1449,8 @@ H5S_hyper_mgath (const void *_buf, size_t elmt_size, #endif /* QAK */ /* Release the memory we allocated */ - H5MM_xfree(lo_bounds); - H5MM_xfree(hi_bounds); + H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,lo_bounds); + H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,hi_bounds); FUNC_LEAVE (num_read); } /* H5S_hyper_mgath() */ @@ -1450,7 +1476,6 @@ static size_t H5S_hyper_mwrite (intn dim, H5S_hyper_io_info_t *io_info) { hsize_t region_size; /* Size of lowest region */ - hid_t reg_id; /* ID of temporary region buffer */ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */ size_t num_regions; /* number of regions overlapped */ size_t i; /* Counters */ @@ -1466,13 +1491,10 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_io_info_t *io_info) /* Get a sorted list (in the next dimension down) of the regions which */ /* overlap the current index in this dim */ - if((reg_id=H5S_hyper_get_regions(&num_regions,dim, + if((regions=H5S_hyper_get_regions(&num_regions,dim, io_info->space->select.sel_info.hslab.hyper_lst->count, io_info->lo_bounds, io_info->hi_bounds, - io_info->iter->hyp.pos,io_info->space->select.offset))>=0) { - - /* Get the pointer to the actual regions array */ - regions=H5TB_buf_ptr(reg_id); + io_info->iter->hyp.pos,io_info->space->select.offset))!=NULL) { #ifdef QAK printf("%s: check 2.0, rank=%d\n", @@ -1568,11 +1590,12 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_io_info_t *io_info) } /* end else */ /* Release the temporary buffer */ - H5TB_release_buf(reg_id); + H5FL_ARR_FREE(H5S_hyper_region_t,regions); } /* end if */ FUNC_LEAVE (num_read); } /* H5S_hyper_mwrite() */ + /*------------------------------------------------------------------------- * Function: H5S_hyper_mscat @@ -1613,10 +1636,8 @@ H5S_hyper_mscat (const void *_tconv_buf, size_t elmt_size, assert (_tconv_buf); /* Allocate space for the low & high bound arrays */ - lo_bounds = H5MM_malloc(mem_space->extent.u.simple.rank * - sizeof(H5S_hyper_bound_t *)); - hi_bounds = H5MM_malloc(mem_space->extent.u.simple.rank * - sizeof(H5S_hyper_bound_t *)); + lo_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,mem_space->extent.u.simple.rank,0); + hi_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,mem_space->extent.u.simple.rank,0); /* * Initialize to correct order to walk through arrays. (When another @@ -1659,11 +1680,12 @@ H5S_hyper_mscat (const void *_tconv_buf, size_t elmt_size, #endif /* QAK */ /* Release the memory we allocated */ - H5MM_xfree(lo_bounds); - H5MM_xfree(hi_bounds); + H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,lo_bounds); + H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,hi_bounds); FUNC_LEAVE (num_read>0 ? SUCCEED : FAIL); } /* H5S_hyper_mscat() */ + /*-------------------------------------------------------------------------- NAME @@ -1760,11 +1782,11 @@ H5S_hyper_node_add (H5S_hyper_node_t **head, intn endflag, intn rank, const hssi assert (size); /* Create new hyperslab node to insert */ - if((slab = H5MM_malloc(sizeof(H5S_hyper_node_t)))==NULL) + if((slab = H5FL_ALLOC(H5S_hyper_node_t,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab node"); - if((slab->start = H5MM_malloc(sizeof(hsize_t)* rank))==NULL) + if((slab->start = H5FL_ARR_ALLOC(hsize_t,rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab start boundary"); - if((slab->end = H5MM_malloc(sizeof(hsize_t)* rank))==NULL) + if((slab->end = H5FL_ARR_ALLOC(hsize_t,rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab end boundary"); /* Set boundary on new node */ @@ -1848,9 +1870,9 @@ H5S_hyper_node_release (H5S_hyper_node_t *node) assert (node); /* Free the hyperslab node */ - node->start = H5MM_xfree(node->start); - node->end = H5MM_xfree(node->end); - H5MM_xfree(node); + H5FL_ARR_FREE(hsize_t,node->start); + H5FL_ARR_FREE(hsize_t,node->end); + H5FL_FREE(H5S_hyper_node_t,node); FUNC_LEAVE (ret_value); } /* H5S_hyper_node_release() */ @@ -1896,11 +1918,11 @@ H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *end) printf("%s: check 1.0\n",FUNC); #endif /* QAK */ /* Create new hyperslab node to insert */ - if((slab = H5MM_malloc(sizeof(H5S_hyper_node_t)))==NULL) + if((slab = H5FL_ALLOC(H5S_hyper_node_t,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab node"); - if((slab->start = H5MM_malloc(sizeof(hsize_t)*space->extent.u.simple.rank))==NULL) + if((slab->start = H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab start boundary"); - if((slab->end = H5MM_malloc(sizeof(hsize_t)*space->extent.u.simple.rank))==NULL) + if((slab->end = H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab end boundary"); #ifdef QAK @@ -1921,7 +1943,6 @@ H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *end) slab->cinfo.cached=0; slab->cinfo.size=elem_count; slab->cinfo.wleft=slab->cinfo.rleft=0; - slab->cinfo.block_id=(-1); slab->cinfo.block=slab->cinfo.wpos=slab->cinfo.rpos=NULL; #ifdef QAK @@ -1935,7 +1956,7 @@ H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *end) #ifdef QAK printf("%s: check 3.1, i=%d, space->sel_info.count=%d, tmp=%p\n",FUNC,(int)i, space->select.sel_info.hslab.hyper_lst->count,tmp); #endif /* QAK */ - if((space->select.sel_info.hslab.hyper_lst->lo_bounds[i]=H5MM_realloc(tmp,sizeof(H5S_hyper_bound_t)*(space->select.sel_info.hslab.hyper_lst->count+1)))==NULL) { + if((space->select.sel_info.hslab.hyper_lst->lo_bounds[i]=H5FL_ARR_REALLOC(H5S_hyper_bound_t,tmp,(space->select.sel_info.hslab.hyper_lst->count+1)))==NULL) { space->select.sel_info.hslab.hyper_lst->lo_bounds[i]=tmp; HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab lo boundary array"); @@ -1944,7 +1965,7 @@ H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *end) printf("%s: check 3.2, i=%d\n",FUNC,(int)i); #endif /* QAK */ tmp=space->select.sel_info.hslab.hyper_lst->hi_bounds[i]; - if((space->select.sel_info.hslab.hyper_lst->hi_bounds[i]=H5MM_realloc(tmp,sizeof(H5S_hyper_bound_t)*(space->select.sel_info.hslab.hyper_lst->count+1)))==NULL) { + if((space->select.sel_info.hslab.hyper_lst->hi_bounds[i]=H5FL_ARR_REALLOC(H5S_hyper_bound_t,tmp,(space->select.sel_info.hslab.hyper_lst->count+1)))==NULL) { space->select.sel_info.hslab.hyper_lst->hi_bounds[i]=tmp; HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab hi boundary array"); @@ -2142,7 +2163,7 @@ H5S_hyper_clip (H5S_t *space, H5S_hyper_node_t *nodes, H5S_hyper_node_t **uniq, H5S_hyper_node_t *region, /* Temp. hyperslab selection region pointer */ *node, /* Temp. hyperslab node pointer */ *next_node; /* Pointer to next node in node list */ - hssize_t *start; /* Temporary arrays of start & sizes (for splitting nodes) */ + hssize_t *start=NULL; /* Temporary arrays of start & sizes (for splitting nodes) */ hsize_t *end=NULL; /* Temporary arrays of start & sizes (for splitting nodes) */ intn rank; /* Cached copy of the rank of the dataspace */ intn overlapped; /* Flag for overlapping nodes */ @@ -2160,9 +2181,9 @@ H5S_hyper_clip (H5S_t *space, H5S_hyper_node_t *nodes, H5S_hyper_node_t **uniq, assert (uniq || overlap); /* Allocate space for the temporary starts & sizes */ - if((start = H5MM_malloc(sizeof(hssize_t)*space->extent.u.simple.rank))==NULL) + if((start = H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab start array"); - if((end = H5MM_malloc(sizeof(hsize_t)*space->extent.u.simple.rank))==NULL) + if((end = H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab size array"); /* Set up local variables */ @@ -2304,9 +2325,9 @@ H5S_hyper_clip (H5S_t *space, H5S_hyper_node_t *nodes, H5S_hyper_node_t **uniq, done: if(start!=NULL) - H5MM_xfree(start); + H5FL_ARR_FREE(hsize_t,start); if(end!=NULL) - H5MM_xfree(end); + H5FL_ARR_FREE(hsize_t,end); FUNC_LEAVE (ret_value); } /* H5S_hyper_clip() */ @@ -2352,19 +2373,19 @@ H5S_hyper_release (H5S_t *space) /* Release the per-dimension selection info */ if(space->select.sel_info.hslab.diminfo!=NULL) - H5MM_xfree(space->select.sel_info.hslab.diminfo); + H5FL_ARR_FREE(H5S_hyper_dim_t,space->select.sel_info.hslab.diminfo); space->select.sel_info.hslab.diminfo = NULL; /* Release hi and lo boundary information */ for(i=0; i<space->extent.u.simple.rank; i++) { - H5MM_xfree(space->select.sel_info.hslab.hyper_lst->lo_bounds[i]); + H5FL_ARR_FREE(H5S_hyper_bound_t,space->select.sel_info.hslab.hyper_lst->lo_bounds[i]); space->select.sel_info.hslab.hyper_lst->lo_bounds[i] = NULL; - H5MM_xfree(space->select.sel_info.hslab.hyper_lst->hi_bounds[i]); + H5FL_ARR_FREE(H5S_hyper_bound_t,space->select.sel_info.hslab.hyper_lst->hi_bounds[i]); space->select.sel_info.hslab.hyper_lst->hi_bounds[i] = NULL; } /* end for */ - H5MM_xfree(space->select.sel_info.hslab.hyper_lst->lo_bounds); + H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,space->select.sel_info.hslab.hyper_lst->lo_bounds); space->select.sel_info.hslab.hyper_lst->lo_bounds = NULL; - H5MM_xfree(space->select.sel_info.hslab.hyper_lst->hi_bounds); + H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,space->select.sel_info.hslab.hyper_lst->hi_bounds); space->select.sel_info.hslab.hyper_lst->hi_bounds = NULL; /* Release list of selected regions */ @@ -2376,7 +2397,7 @@ H5S_hyper_release (H5S_t *space) } /* end while */ /* Release hyperslab selection node itself */ - H5MM_xfree(space->select.sel_info.hslab.hyper_lst); + H5FL_FREE(H5S_hyper_list_t,space->select.sel_info.hslab.hyper_lst); space->select.sel_info.hslab.hyper_lst=NULL; #ifdef QAK @@ -2441,7 +2462,7 @@ H5S_hyper_sel_iter_release (H5S_sel_iter_t *sel_iter) assert (sel_iter); if(sel_iter->hyp.pos!=NULL) - H5MM_xfree(sel_iter->hyp.pos); + H5FL_ARR_FREE(hsize_t,sel_iter->hyp.pos); FUNC_LEAVE (SUCCEED); } /* H5S_hyper_sel_iter_release() */ @@ -2513,7 +2534,7 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src) #endif /* QAK */ if(src->select.sel_info.hslab.diminfo!=NULL) { /* Create the per-dimension selection info */ - if((new_diminfo = H5MM_malloc(sizeof(H5S_hyper_dim_t)*src->extent.u.simple.rank))==NULL) + if((new_diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,src->extent.u.simple.rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension array"); /* Copy the per-dimension selection info */ @@ -2527,7 +2548,7 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src) dst->select.sel_info.hslab.diminfo = new_diminfo; /* Create the new hyperslab information node */ - if((new_hyper = H5MM_malloc(sizeof(H5S_hyper_list_t)))==NULL) + if((new_hyper = H5FL_ALLOC(H5S_hyper_list_t,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node"); @@ -2541,17 +2562,17 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src) printf("%s: check 4.0\n", FUNC); #endif /* QAK */ /* Allocate space for the low & high bound arrays */ - if((new_hyper->lo_bounds = H5MM_malloc(sizeof(H5S_hyper_bound_t *)*src->extent.u.simple.rank))==NULL) + if((new_hyper->lo_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,src->extent.u.simple.rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node"); - if((new_hyper->hi_bounds = H5MM_malloc(sizeof(H5S_hyper_bound_t *)*src->extent.u.simple.rank))==NULL) + if((new_hyper->hi_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,src->extent.u.simple.rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node"); for(i=0; i<src->extent.u.simple.rank; i++) { - if((new_hyper->lo_bounds[i] = H5MM_malloc(sizeof(H5S_hyper_bound_t)*src->select.sel_info.hslab.hyper_lst->count))==NULL) + if((new_hyper->lo_bounds[i] = H5FL_ARR_ALLOC(H5S_hyper_bound_t,src->select.sel_info.hslab.hyper_lst->count,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node"); - if((new_hyper->hi_bounds[i] = H5MM_malloc(sizeof(H5S_hyper_bound_t)*src->select.sel_info.hslab.hyper_lst->count))==NULL) + if((new_hyper->hi_bounds[i] = H5FL_ARR_ALLOC(H5S_hyper_bound_t,src->select.sel_info.hslab.hyper_lst->count,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node"); } /* end for */ @@ -2568,14 +2589,14 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src) printf("%s: check 5.1\n", FUNC); #endif /* QAK */ /* Create each point */ - if((new = H5MM_malloc(sizeof(H5S_hyper_node_t)))==NULL) + if((new = H5FL_ALLOC(H5S_hyper_node_t,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node"); HDmemcpy(new,curr,sizeof(H5S_hyper_node_t)); /* copy caching information */ - if((new->start = H5MM_malloc(src->extent.u.simple.rank*sizeof(hssize_t)))==NULL) + if((new->start = H5FL_ARR_ALLOC(hsize_t,src->extent.u.simple.rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information"); - if((new->end = H5MM_malloc(src->extent.u.simple.rank*sizeof(hssize_t)))==NULL) + if((new->end = H5FL_ARR_ALLOC(hsize_t,src->extent.u.simple.rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information"); HDmemcpy(new->start,curr->start,(src->extent.u.simple.rank*sizeof(hssize_t))); @@ -2607,10 +2628,8 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src) /* Sort the boundary arrays */ for(i=0; i<src->extent.u.simple.rank; i++) { - HDqsort(new_hyper->lo_bounds[i], new_hyper->count, - sizeof(H5S_hyper_bound_t), H5S_hyper_compare_bounds); - HDqsort(new_hyper->hi_bounds[i], new_hyper->count, - sizeof(H5S_hyper_bound_t), H5S_hyper_compare_bounds); + HDqsort(new_hyper->lo_bounds[i], new_hyper->count, sizeof(H5S_hyper_bound_t), H5S_hyper_compare_bounds); + HDqsort(new_hyper->hi_bounds[i], new_hyper->count, sizeof(H5S_hyper_bound_t), H5S_hyper_compare_bounds); } /* end for */ #ifdef QAK printf("%s: check 7.0\n", FUNC); @@ -2837,9 +2856,9 @@ H5S_hyper_select_deserialize (H5S_t *space, const uint8_t *buf) UINT32DECODE(buf,num_elem); /* decode the number of points */ /* Allocate space for the coordinates */ - if((start = H5MM_malloc(rank*sizeof(hssize_t)))==NULL) + if((start = H5FL_ARR_ALLOC(hsize_t,rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information"); - if((count = H5MM_malloc(rank*sizeof(hssize_t)))==NULL) + if((count = H5FL_ARR_ALLOC(hsize_t,rank,0))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information"); /* Retrieve the coordinates from the buffer */ @@ -2863,8 +2882,8 @@ H5S_hyper_select_deserialize (H5S_t *space, const uint8_t *buf) } /* end for */ /* Free temporary buffers */ - H5MM_xfree(start); - H5MM_xfree(count); + H5FL_ARR_FREE(hsize_t,start); + H5FL_ARR_FREE(hsize_t,count); done: FUNC_LEAVE (ret_value); @@ -2986,6 +3005,301 @@ H5S_hyper_select_contiguous(const H5S_t *space) /*------------------------------------------------------------------------- + * Function: H5S_select_hyperslab + * + * Purpose: Internal version of H5Sselect_hyperslab(). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke (split from HSselect_hyperslab()). + * Tuesday, August 25, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, + const hssize_t start[/*space_id*/], + const hsize_t stride[/*space_id*/], + const hsize_t count[/*space_id*/], + const hsize_t block[/*space_id*/]) +{ + hsize_t *_stride=NULL; /* Stride array */ + hsize_t *_block=NULL; /* Block size array */ + hssize_t slab[H5O_LAYOUT_NDIMS]; /* Location of the block to add for strided selections */ + size_t slice[H5O_LAYOUT_NDIMS]; /* Size of preceding dimension's slice */ + H5S_hyper_node_t *add=NULL, /* List of hyperslab nodes to add */ + *uniq=NULL, /* List of unique hyperslab nodes */ + *tmp; /* Temporary hyperslab node */ + uintn acc; /* Accumulator for building slices */ + uintn contig; /* whether selection is contiguous or not */ + int i,j; /* Counters */ + H5S_hyper_dim_t *diminfo; /* per-dimension info for the selection */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5S_select_hyperslab, FAIL); + + /* Check args */ + assert(space); + assert(start); + assert(count); + assert(op>H5S_SELECT_NOOP && op<H5S_SELECT_INVALID); + + /* Fill in the correct stride values */ + if(stride==NULL) { + hssize_t fill=1; + + /* Allocate temporary buffer */ + if ((_stride=H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for stride buffer"); + H5V_array_fill(_stride,&fill,sizeof(hssize_t),space->extent.u.simple.rank); + stride = _stride; + } + + /* Fill in the correct block values */ + if(block==NULL) { + hssize_t fill=1; + + /* Allocate temporary buffer */ + if ((_block=H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for stride buffer"); + H5V_array_fill(_block,&fill,sizeof(hssize_t),space->extent.u.simple.rank); + block = _block; + } + + /* + * Check for overlapping hyperslab blocks in new selection (remove when + * real block-merging algorithm is in place? -QAK). + */ + if(op==H5S_SELECT_SET && block!=NULL) { + for(i=0; i<space->extent.u.simple.rank; i++) { + if(stride[i]<block[i]) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "hyperslab blocks overlap"); + } /* end if */ + } /* end for */ + } /* end if */ + + /* Determine if selection is contiguous */ + /* assume hyperslab is contiguous, until proven otherwise */ + contig=1; + for(i=0; i<space->extent.u.simple.rank; i++) { + /* contiguous hyperslabs have the block size equal to the stride */ + if(stride[i]!=block[i]) { + contig=0; /* hyperslab isn't contiguous */ + break; /* no use looking further */ + } /* end if */ + } /* end for */ + +#ifdef QAK + printf("%s: check 1.0, contig=%d, op=%s\n",FUNC,(int)contig,(op==H5S_SELECT_SET? "H5S_SELECT_SET" : (op==H5S_SELECT_OR ? "H5S_SELECT_OR" : "Unknown"))); +#endif /* QAK */ + /* If we are setting a new selection, remove current selection first */ + if(op==H5S_SELECT_SET) { + if(H5S_select_release(space)<0) { + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, + "can't release hyperslab"); + } /* end if */ + } /* end if */ + +#ifdef QAK + printf("%s: check 2.0, rank=%d\n",FUNC,(int)space->extent.u.simple.rank); +#endif /* QAK */ + /* Allocate space for the hyperslab selection information if necessary */ + if(space->select.type!=H5S_SEL_HYPERSLABS || space->select.sel_info.hslab.hyper_lst==NULL) { + if((space->select.sel_info.hslab.hyper_lst = H5FL_ALLOC(H5S_hyper_list_t,0))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information"); + + /* Set the fields for the hyperslab list */ + space->select.sel_info.hslab.hyper_lst->count=0; + space->select.sel_info.hslab.hyper_lst->head=NULL; + if((space->select.sel_info.hslab.hyper_lst->lo_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,space->extent.u.simple.rank,1))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab lo bound information"); + if((space->select.sel_info.hslab.hyper_lst->hi_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,space->extent.u.simple.rank,1))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab lo bound information"); + } /* end if */ + +#ifdef QAK + printf("%s: check 3.0\n",FUNC); +#endif /* QAK */ + /* Generate list of blocks to add/remove based on selection operation */ + switch(op) { + case H5S_SELECT_SET: + case H5S_SELECT_OR: +#ifdef QAK + printf("%s: check 4.0\n",FUNC); +#endif /* QAK */ + /* Generate list of blocks to add to selection */ + if(contig) { /* Check for trivial case */ +#ifdef QAK + printf("%s: check 4.1\n",FUNC); +#endif /* QAK */ + + /* Account for strides & blocks being equal, but larger than one */ + /* (Why someone would torture us this way, I don't know... -QAK :-) */ + for(i=0; i<space->extent.u.simple.rank; i++) + slab[i]=count[i]*stride[i]; + + /* Add the contiguous hyperslab to the selection */ + if(H5S_hyper_node_add(&add,0,space->extent.u.simple.rank,start,(const hsize_t *)slab)<0) { + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslab"); + } + } else { +#ifdef QAK + printf("%s: check 4.3\n",FUNC); +#endif /* QAK */ + /* Build the slice sizes for each dimension */ + for(i=0, acc=1; i<space->extent.u.simple.rank; i++) { + slice[i]=acc; + acc*=count[i]; + } /* end for */ + + /* Step through all the blocks to add */ + /* (reuse the count in ACC above) */ + /* Adding the blocks in reverse order reduces the time spent moving memory around in H5S_hyper_add() */ + for(i=(int)acc-1; i>=0; i--) { + /* Build the location of the block */ + for(j=0; j<space->extent.u.simple.rank; j++) + slab[j]=start[j]+((i/slice[j])%count[j])*stride[j]; + + /* Add the block to the list of hyperslab selections */ + if(H5S_hyper_node_add(&add,0,space->extent.u.simple.rank,(const hssize_t *)slab, (const hsize_t *)block)<0) { + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslab"); + } /* end if */ + } /* end for */ + } /* end else */ + +#ifdef QAK + printf("%s: check 4.5\n",FUNC); +#endif /* QAK */ + /* Clip list of new blocks to add against current selection */ + if(op==H5S_SELECT_OR) { + H5S_hyper_clip(space,add,&uniq,NULL); + add=uniq; + } /* end if */ + else { + /* Copy all the per-dimension selection info into the space descriptor */ + if((diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank,0))==NULL) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector"); + } /* end if */ + for(i=0; i<space->extent.u.simple.rank; i++) { + diminfo[i].start = start[i]; + diminfo[i].stride = stride[i]; + diminfo[i].count = count[i]; + diminfo[i].block = block[i]; + } /* end for */ + space->select.sel_info.hslab.diminfo = diminfo; + } /* end else */ + break; + + default: + HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation"); + } /* end switch */ + +#ifdef QAK + printf("%s: check 5.0\n",FUNC); +#endif /* QAK */ + /* Add new blocks to current selection */ + while(add!=NULL) { + tmp=add->next; + + /* Add new block */ + if(H5S_hyper_add(space,(const hssize_t *)add->start, (const hsize_t *)add->end)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslab"); + + /* Free node in list */ + H5S_hyper_node_release(add); + + /* Go to next node */ + add=tmp; + } /* end while */ + + /* Merge blocks for better I/O performance */ + /* Regenerate lo/hi bounds arrays? */ + +#ifdef QAK + printf("%s: check 6.0\n",FUNC); +#endif /* QAK */ + + /* Set selection type */ + space->select.type=H5S_SEL_HYPERSLABS; + ret_value=SUCCEED; + +done: + if(_stride!=NULL) + H5FL_ARR_FREE(hsize_t,_stride); + if(_block!=NULL) + H5FL_ARR_FREE(hsize_t,_block); + FUNC_LEAVE (ret_value); +} + + +/*-------------------------------------------------------------------------- + NAME + H5Sselect_hyperslab + PURPOSE + Specify a hyperslab to combine with the current hyperslab selection + USAGE + herr_t H5Sselect_hyperslab(dsid, op, start, stride, count, block) + hid_t dsid; IN: Dataspace ID of selection to modify + H5S_seloper_t op; IN: Operation to perform on current selection + const hssize_t *start; IN: Offset of start of hyperslab + const hssize_t *stride; IN: Hyperslab stride + const hssize_t *count; IN: Number of blocks included in hyperslab + const hssize_t *block; IN: Size of block in hyperslab + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Combines a hyperslab selection with the current selection for a dataspace. + If the current selection is not a hyperslab, it is freed and the hyperslab + parameters passed in are combined with the H5S_SEL_ALL hyperslab (ie. a + selection composing the entire current extent). Currently, only the + H5S_SELECT_SET & H5S_SELECT_OR operations are supported. If STRIDE or + BLOCK is NULL, they are assumed to be set to all '1'. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, + const hssize_t start[/*space_id*/], + const hsize_t _stride[/*space_id*/], + const hsize_t count[/*space_id*/], + const hsize_t _block[/*space_id*/]) +{ + H5S_t *space = NULL; /* Dataspace to modify selection of */ + + FUNC_ENTER (H5Sselect_hyperslab, FAIL); + H5TRACE6("e","iSs*[a0]Hs*[a0]h*[a0]h*[a0]h",space_id,op,start,_stride, + count,_block); + + /* Check args */ + if (H5I_DATASPACE != H5I_get_type(space_id) || + NULL == (space=H5I_object(space_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space"); + } + if(start==NULL || count==NULL) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified"); + } /* end if */ + + if(!(op>H5S_SELECT_NOOP && op<H5S_SELECT_INVALID)) { + HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation"); + } /* end if */ + + if (H5S_select_hyperslab(space, op, start, _stride, count, _block)<0) { + HRETURN_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, + "unable to set hyperslab selection"); + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- * Function: H5S_hyper_select_iterate_mem * * Purpose: Recursively iterates over data points in memory using the parameters @@ -3007,7 +3321,6 @@ H5S_hyper_select_iterate_mem (intn dim, H5S_hyper_iter_info_t *iter_info) { hsize_t offset; /* offset of region in buffer */ void *tmp_buf; /* temporary location of the element in the buffer */ - hid_t reg_id; /* ID of temporary region buffer */ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */ size_t num_regions; /* number of regions overlapped */ herr_t user_ret=0; /* User's return value */ @@ -3020,13 +3333,10 @@ H5S_hyper_select_iterate_mem (intn dim, H5S_hyper_iter_info_t *iter_info) /* Get a sorted list (in the next dimension down) of the regions which */ /* overlap the current index in this dim */ - if((reg_id=H5S_hyper_get_regions(&num_regions,dim, + if((regions=H5S_hyper_get_regions(&num_regions,dim, iter_info->space->select.sel_info.hslab.hyper_lst->count, iter_info->lo_bounds, iter_info->hi_bounds, - iter_info->iter->hyp.pos,iter_info->space->select.offset))>=0) { - - /* Get the pointer to the actual regions array */ - regions=H5TB_buf_ptr(reg_id); + iter_info->iter->hyp.pos,iter_info->space->select.offset))!=NULL) { /* Check if this is the second to last dimension in dataset */ /* (Which means that we've got a list of the regions in the fastest */ @@ -3092,7 +3402,7 @@ H5S_hyper_select_iterate_mem (intn dim, H5S_hyper_iter_info_t *iter_info) } /* end else */ /* Release the temporary buffer */ - H5TB_release_buf(reg_id); + H5FL_ARR_FREE(H5S_hyper_region_t,regions); } /* end if */ FUNC_LEAVE (user_ret); @@ -3161,8 +3471,8 @@ H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t } /* Allocate space for the low & high bound arrays */ - lo_bounds = H5MM_malloc(space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *)); - hi_bounds = H5MM_malloc(space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *)); + lo_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,space->extent.u.simple.rank,0); + hi_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,space->extent.u.simple.rank,0); /* * Initialize to correct order to walk through arrays. (When another @@ -3196,8 +3506,8 @@ H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t ret_value=H5S_hyper_select_iterate_mem(-1,&iter_info); /* Release the memory we allocated */ - H5MM_xfree(lo_bounds); - H5MM_xfree(hi_bounds); + H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,lo_bounds); + H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,hi_bounds); /* Release selection iterator */ H5S_sel_iter_release(space,&iter); |