summaryrefslogtreecommitdiffstats
path: root/src/H5FD.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2002-06-05 15:23:20 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2002-06-05 15:23:20 (GMT)
commit6b1208407f5886c917f1ebb38bac058eeb980e30 (patch)
tree6b29e7da66abf76d1ed3e1b7ea52b7a7638f3534 /src/H5FD.c
parentc72c322f6265f121cfd2542f081875f42c9d6fed (diff)
downloadhdf5-6b1208407f5886c917f1ebb38bac058eeb980e30.zip
hdf5-6b1208407f5886c917f1ebb38bac058eeb980e30.tar.gz
hdf5-6b1208407f5886c917f1ebb38bac058eeb980e30.tar.bz2
[svn-r5536] Purpose:
New feature. Description: Added a "small data" block allocation mechanism to the library, similar to the mechanism used for allocating metadata currently. See the RFC for more details: http://hdf.ncsa.uiuc.edu/RFC/SmallData/SmallData.html This reduces the number of I/O operations which hit the disk for my test program from 19 to 15 (i.e. from 393 to 15, overall). Platforms tested: Solaris 2.7 (arabica) w/FORTRAN and FreeBSD 4.5 (sleipnir) w/C++
Diffstat (limited to 'src/H5FD.c')
-rw-r--r--src/H5FD.c182
1 files changed, 129 insertions, 53 deletions
diff --git a/src/H5FD.c b/src/H5FD.c
index 55c8847..fe43159 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -775,6 +775,7 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
H5FD_t *file=NULL;
hid_t driver_id = -1;
size_t meta_block_size=0;
+ size_t sdata_block_size=0;
H5P_genplist_t *plist; /* Property list pointer */
FUNC_ENTER_NOAPI(H5FD_open, NULL);
@@ -815,6 +816,9 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(meta_block_size)) < 0)
HRETURN_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get meta data block size");
file->def_meta_block_size = meta_block_size;
+ if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(sdata_block_size)) < 0)
+ HRETURN_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' block size");
+ file->def_sdata_block_size = sdata_block_size;
file->accum_loc = HADDR_UNDEF;
if(H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(file->threshold)) < 0)
HRETURN_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold");
@@ -1420,72 +1424,144 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
}
#endif
- /*
- * If the metadata aggregation feature is enabled for this VFL driver,
- * allocate "generic" metadata space and sub-allocate out of that, if
- * possible. Otherwise just allocate through H5FD_real_alloc()
- */
- /* Allocate all types of metadata out of the metadata block */
- if((file->feature_flags&H5FD_FEAT_AGGREGATE_METADATA) && type!=H5FD_MEM_DRAW) {
- /* Check if the space requested is larger than the space left in the block */
- if(size>file->cur_meta_block_size) {
- haddr_t new_meta; /* Address for new metadata */
-
- /* Check if the block asked for is too large for a metadata block */
- if(size>=file->def_meta_block_size) {
- /* Allocate more room for this new block the regular way */
- new_meta=H5FD_real_alloc(file,type,size);
-
- /* Check if the new metadata is at the end of the current metadata block */
- if(file->eoma+file->cur_meta_block_size==new_meta) {
- /* Treat the allocation request as if the current metadata block
- * grew by the amount allocated and just update the eoma
- * address. Don't bother updating the cur_meta_block_size
- * since it will just grow and shrink by the same amount.
- */
- ret_value=file->eoma;
- file->eoma+=size;
+ /* Handle metadata differently from "raw" data */
+ if(type!=H5FD_MEM_DRAW) {
+ /*
+ * If the metadata aggregation feature is enabled for this VFL driver,
+ * allocate "generic" metadata space and sub-allocate out of that, if
+ * possible. Otherwise just allocate through H5FD_real_alloc()
+ */
+ /* Allocate all types of metadata out of the metadata block */
+ if(file->feature_flags&H5FD_FEAT_AGGREGATE_METADATA) {
+ /* Check if the space requested is larger than the space left in the block */
+ if(size>file->cur_meta_block_size) {
+ haddr_t new_meta; /* Address for new metadata */
+
+ /* Check if the block asked for is too large for a metadata block */
+ if(size>=file->def_meta_block_size) {
+ /* Allocate more room for this new block the regular way */
+ new_meta=H5FD_real_alloc(file,type,size);
+
+ /* Check if the new metadata is at the end of the current metadata block */
+ if(file->eoma+file->cur_meta_block_size==new_meta) {
+ /* Treat the allocation request as if the current metadata block
+ * grew by the amount allocated and just update the eoma
+ * address. Don't bother updating the cur_meta_block_size
+ * since it will just grow and shrink by the same amount.
+ */
+ ret_value=file->eoma;
+ file->eoma+=size;
+ } /* end if */
+ else {
+ /* Use the new metadata block for the space allocated */
+ ret_value=new_meta;
+ } /* end else */
} /* end if */
else {
- /* Use the new metadata block for the space allocated */
- ret_value=new_meta;
- } /* end else */
- } /* end if */
- else {
- /* Allocate another metadata block */
- new_meta=H5FD_real_alloc(file,H5FD_MEM_DEFAULT,file->def_meta_block_size);
+ /* Allocate another metadata block */
+ new_meta=H5FD_real_alloc(file,H5FD_MEM_DEFAULT,file->def_meta_block_size);
- /* Check if the new metadata is at the end of the current metadata block */
- if(file->eoma+file->cur_meta_block_size==new_meta) {
- file->cur_meta_block_size+=file->def_meta_block_size;
- } /* end if */
- else {
- /*
- * Instead of just dropping the remainder of the block on the
- * floor and leaving the space in the file unused, we should
- * return this small piece of unused space to the free list
- * management. - QAK
- */
- file->eoma=new_meta;
- file->cur_meta_block_size=file->def_meta_block_size;
- } /* end else */
+ /* Check if the new metadata is at the end of the current metadata block */
+ if(file->eoma+file->cur_meta_block_size==new_meta) {
+ file->cur_meta_block_size+=file->def_meta_block_size;
+ } /* end if */
+ else {
+ /*
+ * Instead of just dropping the remainder of the block on the
+ * floor and leaving the space in the file unused, we should
+ * return this small piece of unused space to the free list
+ * management. - QAK
+ */
+ file->eoma=new_meta;
+ file->cur_meta_block_size=file->def_meta_block_size;
+ } /* end else */
+ /* Allocate space out of the metadata block */
+ ret_value=file->eoma;
+ file->cur_meta_block_size-=size;
+ file->eoma+=size;
+ } /* end else */
+ } /* end if */
+ else {
/* Allocate space out of the metadata block */
ret_value=file->eoma;
file->cur_meta_block_size-=size;
file->eoma+=size;
} /* end else */
} /* end if */
- else {
- /* Allocate space out of the metadata block */
- ret_value=file->eoma;
- file->cur_meta_block_size-=size;
- file->eoma+=size;
+ else { /* Allocate data the regular way */
+ ret_value=H5FD_real_alloc(file,type,size);
} /* end else */
} /* end if */
- else { /* Allocate data the regular way */
- ret_value=H5FD_real_alloc(file,type,size);
+ else { /* Allocate "raw" data */
+ /*
+ * If the "small data" aggregation feature is enabled for this VFL driver,
+ * allocate "small data" space and sub-allocate out of that, if
+ * possible. Otherwise just allocate through H5FD_real_alloc()
+ */
+ if(file->feature_flags&H5FD_FEAT_AGGREGATE_SMALLDATA) {
+ /* Check if the space requested is larger than the space left in the block */
+ if(size>file->cur_sdata_block_size) {
+ haddr_t new_data; /* Address for new raw data block */
+
+ /* Check if the block asked for is too large for the "small data" block */
+ if(size>=file->def_sdata_block_size) {
+ /* Allocate more room for this new block the regular way */
+ new_data=H5FD_real_alloc(file,type,size);
+
+ /* Check if the new raw data is at the end of the current "small data" block */
+ if(file->eosda+file->cur_sdata_block_size==new_data) {
+ /* Treat the allocation request as if the current "small data"
+ * block grew by the amount allocated and just update the
+ * eosda address. Don't bother updating the
+ * cur_sdata_block_size since it will just grow and shrink by
+ * the same amount.
+ */
+ ret_value=file->eosda;
+ file->eosda+=size;
+ } /* end if */
+ else {
+ /* Use the new "small data" block for the space allocated */
+ ret_value=new_data;
+ } /* end else */
+ } /* end if */
+ else {
+ /* Allocate another "small data" block */
+ new_data=H5FD_real_alloc(file,type,file->def_sdata_block_size);
+
+ /* Check if the new raw data is at the end of the current "small data" block */
+ if(file->eosda+file->cur_sdata_block_size==new_data) {
+ file->cur_sdata_block_size+=file->def_sdata_block_size;
+ } /* end if */
+ else {
+ /*
+ * Instead of just dropping the remainder of the block on the
+ * floor and leaving the space in the file unused, we should
+ * return this small piece of unused space to the free list
+ * management. - QAK
+ */
+ file->eosda=new_data;
+ file->cur_sdata_block_size=file->def_sdata_block_size;
+ } /* end else */
+
+
+ /* Allocate space out of the "small data" block */
+ ret_value=file->eosda;
+ file->cur_sdata_block_size-=size;
+ file->eosda+=size;
+ } /* end else */
+ } /* end if */
+ else {
+ /* Allocate space out of the "small data" block */
+ ret_value=file->eosda;
+ file->cur_sdata_block_size-=size;
+ file->eosda+=size;
+ } /* end else */
+ } /* end if */
+ else { /* Allocate data the regular way */
+ ret_value=H5FD_real_alloc(file,type,size);
+ } /* end else */
} /* end else */
done: