mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-27 02:10:55 +08:00
[svn-r5959]
Purpose: Performance improvement for compact dataset. Platforms tested: Linux 2.2(eirene), Solaris 2.7(arabica), IRIX64 6.5(modi4)
This commit is contained in:
parent
acb356d309
commit
bc6f56390a
@ -1531,6 +1531,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
|
||||
H5D_fill_value_t fill_status;
|
||||
H5P_genplist_t *plist; /* Property list */
|
||||
H5P_genplist_t *new_plist; /* New Property list */
|
||||
size_t ohdr_size=H5D_MINHDR_SIZE; /* Size of dataset's object header */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5D_create, NULL);
|
||||
|
||||
@ -1708,6 +1709,8 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
|
||||
if ((ndims=H5S_get_simple_extent_dims(space, new_dset->layout.dim, max_dim))<0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize dimension size of compact dataset storage");
|
||||
/* remember to check if size is small enough to fit header message */
|
||||
ohdr_size+=new_dset->layout.size;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1715,7 +1718,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
|
||||
} /* end switch */
|
||||
|
||||
/* Create (open for write access) an object header */
|
||||
if (H5O_create(f, 256, &(new_dset->ent)) < 0)
|
||||
if (H5O_create(f, ohdr_size, &(new_dset->ent)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to create dataset object header");
|
||||
|
||||
/* Retrieve properties of fill value and others. Copy them into new fill
|
||||
|
@ -39,7 +39,7 @@
|
||||
#define H5D_RESERVED_ATOMS 0
|
||||
|
||||
/* Set the minimum object header size to create objects with */
|
||||
#define H5D_MINHDR_SIZE 512
|
||||
#define H5D_MINHDR_SIZE 256
|
||||
|
||||
/* ======== Dataset creation properties ======== */
|
||||
/* Definitions for storage layout property */
|
||||
|
253
src/H5FD.c
253
src/H5FD.c
@ -1757,114 +1757,179 @@ H5FD_free(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size)
|
||||
* driver deallocate the memory.
|
||||
*/
|
||||
if (mapped_type>=0) {
|
||||
H5FD_free_t *last; /* Last merged node */
|
||||
H5FD_free_t *last_prev=NULL;/* Pointer to node before merged node */
|
||||
H5FD_free_t *curr; /* Current free block being inspected */
|
||||
H5FD_free_t *prev; /* Previous free block being inspected */
|
||||
|
||||
/* Adjust the metadata accumulator to remove the freed block, if it overlaps */
|
||||
if((file->feature_flags&H5FD_FEAT_ACCUMULATE_METADATA)
|
||||
&& H5F_addr_overlap(addr,size,file->accum_loc,file->accum_size)) {
|
||||
size_t overlap_size; /* Size of overlap with accumulator */
|
||||
|
||||
/* Check for overlapping the beginning of the accumulator */
|
||||
if(H5F_addr_le(addr,file->accum_loc)) {
|
||||
/* Check for completely overlapping the accumulator */
|
||||
if(H5F_addr_ge(addr+size,file->accum_loc+file->accum_size)) {
|
||||
/* Reset the entire accumulator */
|
||||
file->accum_loc=HADDR_UNDEF;
|
||||
file->accum_size=FALSE;
|
||||
file->accum_dirty=FALSE;
|
||||
} /* end if */
|
||||
/* Block to free must end within the accumulator */
|
||||
else {
|
||||
size_t new_accum_size; /* Size of new accumulator buffer */
|
||||
|
||||
/* Calculate the size of the overlap with the accumulator, etc. */
|
||||
overlap_size=(addr+size)-file->accum_loc;
|
||||
new_accum_size=file->accum_size-overlap_size;
|
||||
|
||||
/* Move the accumulator buffer information to eliminate the freed block */
|
||||
HDmemmove(file->meta_accum,file->meta_accum+overlap_size,new_accum_size);
|
||||
|
||||
/* Adjust the accumulator information */
|
||||
file->accum_loc+=overlap_size;
|
||||
file->accum_size=new_accum_size;
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
/* Block to free must start within the accumulator */
|
||||
else {
|
||||
/* Calculate the size of the overlap with the accumulator */
|
||||
overlap_size=(file->accum_loc+file->accum_size)-addr;
|
||||
|
||||
/* Block to free is in the middle of the accumulator */
|
||||
if(H5F_addr_lt(addr,file->accum_loc+file->accum_size)) {
|
||||
haddr_t tail_addr;
|
||||
hsize_t tail_size;
|
||||
|
||||
/* Calculate the address & size of the tail to write */
|
||||
tail_addr=addr+size;
|
||||
tail_size=(file->accum_loc+file->accum_size)-tail_addr;
|
||||
|
||||
/* Write out the part of the accumulator after the block to free */
|
||||
if (H5FD_write(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, tail_addr, tail_size, file->meta_accum+(tail_addr-file->accum_loc))<0)
|
||||
HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed");
|
||||
} /* end if */
|
||||
|
||||
/* Adjust the accumulator information */
|
||||
file->accum_size=file->accum_size-overlap_size;
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
|
||||
/* Scan through the existing blocks for the mapped type to see if we can extend one */
|
||||
curr=file->fl[mapped_type];
|
||||
prev=NULL;
|
||||
last=prev=NULL;
|
||||
while(curr!=NULL) {
|
||||
/* Check if the block to free adjoins the start of the current block */
|
||||
if((addr+size)==curr->addr) {
|
||||
/* If we previously found & merged a node, eliminate it from the list & free it */
|
||||
if(last!=NULL) {
|
||||
/* Check if there was a previous block in the list */
|
||||
if(last_prev!=NULL)
|
||||
/* Eliminate the merged block from the list */
|
||||
last_prev->next=last->next;
|
||||
/* No previous block, this must be the head of the list */
|
||||
else
|
||||
/* Eliminate the merged block from the list */
|
||||
file->fl[mapped_type] = last->next;
|
||||
|
||||
/* Check for eliminating the block before the 'current' one */
|
||||
if(last==prev)
|
||||
prev=last_prev;
|
||||
|
||||
/* Free the memory for the merged block */
|
||||
H5FL_FREE(H5FD_free_t,last);
|
||||
} /* end if */
|
||||
|
||||
/* Adjust the address and size of the block found */
|
||||
curr->addr=addr;
|
||||
curr->size+=size;
|
||||
|
||||
/* Break out of loop */
|
||||
break;
|
||||
/* Adjust the information about to memory block to include the merged block */
|
||||
addr=curr->addr;
|
||||
size=curr->size;
|
||||
|
||||
/* Update the information about the merged node */
|
||||
last=curr;
|
||||
last_prev=prev;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Check if the block to free adjoins the end of the current block */
|
||||
if((curr->addr+curr->size)==addr) {
|
||||
/* If we previously found & merged a node, eliminate it from the list & free it */
|
||||
if(last!=NULL) {
|
||||
/* Check if there was a previous block in the list */
|
||||
if(last_prev!=NULL)
|
||||
/* Eliminate the merged block from the list */
|
||||
last_prev->next=last->next;
|
||||
/* No previous block, this must be the head of the list */
|
||||
else
|
||||
/* Eliminate the merged block from the list */
|
||||
file->fl[mapped_type] = last->next;
|
||||
|
||||
/* Check for eliminating the block before the 'current' one */
|
||||
if(last==prev)
|
||||
prev=last_prev;
|
||||
|
||||
/* Free the memory for the merged block */
|
||||
H5FL_FREE(H5FD_free_t,last);
|
||||
} /* end if */
|
||||
|
||||
/* Adjust the size of the block found */
|
||||
curr->size+=size;
|
||||
|
||||
/* Break out of loop */
|
||||
break;
|
||||
/* Adjust the information about to memory block to include the merged block */
|
||||
size=curr->size;
|
||||
|
||||
/* Update the information about the merged node */
|
||||
last=curr;
|
||||
last_prev=prev;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Advance to next node in list */
|
||||
prev=curr;
|
||||
curr=curr->next;
|
||||
} /* end else */
|
||||
} /* end else */
|
||||
|
||||
/* Advance to next node in list */
|
||||
prev=curr;
|
||||
curr=curr->next;
|
||||
} /* end while */
|
||||
|
||||
/* Check if we adjusted an existing block */
|
||||
if(curr!=NULL) {
|
||||
H5FD_free_t *merge_curr; /* Current free block for merging */
|
||||
H5FD_free_t *merge_prev; /* Previous free block for merging */
|
||||
|
||||
|
||||
/* Scan through the existing blocks for the mapped type to see if we can merge the block we just found */
|
||||
merge_curr=file->fl[mapped_type];
|
||||
merge_prev=NULL;
|
||||
while(merge_curr!=NULL) {
|
||||
/* Check if the found block adjoins the start of the current block */
|
||||
if((curr->addr+curr->size)==merge_curr->addr) {
|
||||
/* Adjust the size of the block found */
|
||||
curr->size+=merge_curr->size;
|
||||
|
||||
/* Break out of loop */
|
||||
break;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Check if the found block adjoins the end of the current block */
|
||||
if((merge_curr->addr+merge_curr->size)==curr->addr) {
|
||||
/* Adjust the address and size of the block found */
|
||||
curr->addr=merge_curr->addr;
|
||||
curr->size+=merge_curr->size;
|
||||
|
||||
/* Break out of loop */
|
||||
break;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Advance to next node in list */
|
||||
merge_prev=merge_curr;
|
||||
merge_curr=merge_curr->next;
|
||||
} /* end else */
|
||||
} /* end else */
|
||||
} /* end while */
|
||||
|
||||
/* Check if we merged a block out of existance */
|
||||
if(merge_curr!=NULL) {
|
||||
/* Check if there was a previous block in the list */
|
||||
if(merge_prev!=NULL)
|
||||
/* Eliminate the merged block from the list */
|
||||
merge_prev->next=merge_curr->next;
|
||||
/* No previous block, this must be the head of the list */
|
||||
else
|
||||
/* Eliminate the merged block from the list */
|
||||
file->fl[mapped_type] = merge_curr->next;
|
||||
|
||||
/* Check for eliminating the block before the 'found' one */
|
||||
if(merge_curr==prev)
|
||||
prev=merge_prev;
|
||||
|
||||
/* Free the memory for the merged block */
|
||||
H5FL_FREE(H5FD_free_t,merge_curr);
|
||||
} /* end if */
|
||||
|
||||
if(last!=NULL) {
|
||||
/* Move the node found to the front, if it wasn't already there */
|
||||
if(prev!=NULL) {
|
||||
prev->next=curr->next;
|
||||
curr->next = file->fl[mapped_type];
|
||||
file->fl[mapped_type] = curr;
|
||||
if(last_prev!=NULL) {
|
||||
last_prev->next=last->next;
|
||||
last->next = file->fl[mapped_type];
|
||||
file->fl[mapped_type] = last;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
else {
|
||||
/* Allocate a new node to hold the free block's information */
|
||||
if(NULL==(curr = H5FL_ALLOC(H5FD_free_t,0)))
|
||||
if(NULL==(last = H5FL_ALLOC(H5FD_free_t,0)))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate node for free space info");
|
||||
|
||||
curr->addr = addr;
|
||||
curr->size = size;
|
||||
curr->next = file->fl[mapped_type];
|
||||
file->fl[mapped_type] = curr;
|
||||
last->addr = addr;
|
||||
last->size = size;
|
||||
last->next = file->fl[mapped_type];
|
||||
file->fl[mapped_type] = last;
|
||||
} /* end else */
|
||||
|
||||
/* Check if we increased the size of the largest block on the list */
|
||||
file->maxsize = MAX(file->maxsize, curr->size);
|
||||
file->maxsize = MAX(file->maxsize, last->size);
|
||||
|
||||
/* Check if this free block is at the end of file allocated space.
|
||||
* Truncate it if this is true. */
|
||||
if(file->cls->get_eoa) {
|
||||
haddr_t eoa;
|
||||
eoa = file->cls->get_eoa(file);
|
||||
if(eoa == (last->addr+last->size)) {
|
||||
if(file->cls->set_eoa(file, last->addr) < 0)
|
||||
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "set end of space allocation request failed");
|
||||
/* Remove this free block from the list */
|
||||
file->fl[mapped_type] = last->next;
|
||||
if(file->maxsize==last->size)
|
||||
file->maxsize=0; /*unknown*/
|
||||
H5FL_FREE(H5FD_free_t, last);
|
||||
}
|
||||
}
|
||||
} else if (file->cls->free) {
|
||||
if ((file->cls->free)(file, type, addr, size)<0)
|
||||
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver free request failed");
|
||||
@ -2567,12 +2632,12 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si
|
||||
if((addr+size)==file->accum_loc) {
|
||||
/* Check if we need more buffer space */
|
||||
if((size+file->accum_size)>file->accum_buf_size) {
|
||||
/* Reallocate the metadata accumulator buffer */
|
||||
if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,size+file->accum_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer");
|
||||
/* Adjust the buffer size, by doubling it */
|
||||
file->accum_buf_size = MAX(file->accum_buf_size*2,size+file->accum_size);
|
||||
|
||||
/* Note the new buffer size */
|
||||
file->accum_buf_size=size+file->accum_size;
|
||||
/* Reallocate the metadata accumulator buffer */
|
||||
if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,file->accum_buf_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer");
|
||||
} /* end if */
|
||||
|
||||
/* Move the existing metadata to the proper location */
|
||||
@ -2592,12 +2657,12 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si
|
||||
else if(addr==(file->accum_loc+file->accum_size)) {
|
||||
/* Check if we need more buffer space */
|
||||
if((size+file->accum_size)>file->accum_buf_size) {
|
||||
/* Reallocate the metadata accumulator buffer */
|
||||
if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,size+file->accum_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer");
|
||||
/* Adjust the buffer size, by doubling it */
|
||||
file->accum_buf_size = MAX(file->accum_buf_size*2,size+file->accum_size);
|
||||
|
||||
/* Note the new buffer size */
|
||||
file->accum_buf_size=size+file->accum_size;
|
||||
/* Reallocate the metadata accumulator buffer */
|
||||
if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,file->accum_buf_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer");
|
||||
} /* end if */
|
||||
|
||||
/* Copy the new metadata to the end */
|
||||
@ -2624,12 +2689,12 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si
|
||||
|
||||
/* Check if we need more buffer space */
|
||||
if(new_size>file->accum_buf_size) {
|
||||
/* Reallocate the metadata accumulator buffer */
|
||||
if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,new_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer");
|
||||
/* Adjust the buffer size, by doubling it */
|
||||
file->accum_buf_size = MAX(file->accum_buf_size*2,new_size);
|
||||
|
||||
/* Note the new buffer size */
|
||||
file->accum_buf_size=new_size;
|
||||
/* Reallocate the metadata accumulator buffer */
|
||||
if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,file->accum_buf_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer");
|
||||
} /* end if */
|
||||
|
||||
/* Calculate the proper offset of the existing metadata */
|
||||
@ -2655,12 +2720,12 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si
|
||||
|
||||
/* Check if we need more buffer space */
|
||||
if(new_size>file->accum_buf_size) {
|
||||
/* Reallocate the metadata accumulator buffer */
|
||||
if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,new_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer");
|
||||
/* Adjust the buffer size, by doubling it */
|
||||
file->accum_buf_size = MAX(file->accum_buf_size*2,new_size);
|
||||
|
||||
/* Note the new buffer size */
|
||||
file->accum_buf_size=new_size;
|
||||
/* Reallocate the metadata accumulator buffer */
|
||||
if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,file->accum_buf_size))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer");
|
||||
} /* end if */
|
||||
|
||||
/* Copy the new metadata to the end */
|
||||
|
@ -76,6 +76,7 @@ typedef struct H5FL_reg_head_t {
|
||||
*/
|
||||
|
||||
#else /* H5_NO_REG_FREE_LISTS */
|
||||
#include "H5MMprivate.h"
|
||||
#define H5FL_DEFINE(t) int t##_reg_free_list_placeholder
|
||||
#define H5FL_EXTERN(t) extern int t##_reg_free_list_placeholder
|
||||
#define H5FL_DEFINE_STATIC(t) static H5FL_DEFINE(t)
|
||||
|
Loading…
Reference in New Issue
Block a user