diff options
Diffstat (limited to 'src/H5HFhdr.c')
-rw-r--r-- | src/H5HFhdr.c | 84 |
1 files changed, 63 insertions, 21 deletions
diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index a0af4b1..8376da4 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -232,7 +232,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5HF_hdr_finish_init_pahse2 + * Function: H5HF_hdr_finish_init_phase2 * * Purpose: Second phase to finish initializing info in shared heap header * @@ -281,7 +281,11 @@ HDfprintf(stderr, "%s: row_max_dblock_free[%Zu] = %Zu\n", FUNC, u, hdr->man_dtab /* Initialize the information for tracking 'huge' objects */ if(H5HF_huge_init(hdr) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't informan for tracking huge objects") + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize info for tracking huge objects") + + /* Initialize the information for tracking 'tiny' objects */ + if(H5HF_tiny_init(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize info for tracking tiny objects") done: FUNC_LEAVE_NOAPI(ret_value) @@ -343,7 +347,6 @@ haddr_t H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) { H5HF_hdr_t *hdr = NULL; /* The new fractal heap header information */ - haddr_t hdr_addr; /* Heap header address */ size_t dblock_overhead; /* Direct block's overhead */ haddr_t ret_value; /* Return value */ @@ -388,12 +391,7 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, HADDR_UNDEF, "max. heap size too large for file") #endif /* NDEBUG */ - /* Allocate space for the header on disk */ - if(HADDR_UNDEF == (hdr_addr = H5MF_alloc(f, H5FD_MEM_FHEAP_HDR, dxpl_id, (hsize_t)H5HF_HEADER_SIZE(hdr)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for fractal heap header") - /* Set the creation parameters for the heap */ - hdr->heap_addr = hdr_addr; hdr->max_man_size = cparam->max_man_size; HDmemcpy(&(hdr->man_dtable.cparam), &(cparam->managed), sizeof(H5HF_dtable_cparam_t)); @@ -410,9 +408,37 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) hdr->dirty = TRUE; /* First phase of header final initialization */ + /* (doesn't need ID length set up) */ if(H5HF_hdr_finish_init_phase1(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't finish phase #1 of header final initialization") + /* Copy any I/O filter pipeline */ + /* (This code is not in the "finish init phase" routines because those + * routines are also called from the cache 'load' callback, and the filter + * length is already set in that case (its stored in the header on disk)) + */ + if(cparam->pline.nused > 0) { + /* Copy the I/O filter pipeline from the creation parameters to the header */ + if(NULL == H5O_copy(H5O_PLINE_ID, &(cparam->pline), &(hdr->pline))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTCOPY, HADDR_UNDEF, "can't copy I/O filter pipeline") + + /* Compute the I/O filters' encoded size */ + if(0 == (hdr->filter_len = H5O_raw_size(H5O_PLINE_ID, hdr->f, &(hdr->pline)))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGETSIZE, HADDR_UNDEF, "can't get I/O filter pipeline size") +#ifdef QAK +HDfprintf(stderr, "%s: hdr->filter_len = %u\n", FUNC, hdr->filter_len); +#endif /* QAK */ + + /* Compute size of header on disk */ + hdr->heap_size = H5HF_HEADER_SIZE(hdr) /* Base header size */ + + hdr->sizeof_size /* Size of size for filtered root direct block */ + + 4 /* Size of filter mask for filtered root direct block */ + + hdr->filter_len; /* Size of encoded I/O filter info */ + } /* end if */ + else + /* Set size of header on disk */ + hdr->heap_size = H5HF_HEADER_SIZE(hdr); + /* Set the length of IDs in the heap */ /* (This code is not in the "finish init phase" routines because those * routines are also called from the cache 'load' callback, and the ID @@ -423,39 +449,55 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) hdr->id_len = 1 + hdr->heap_off_size + hdr->heap_len_size; break; - case 1: /* Set the length of heap IDs to just enough to hold the file offset & length of 'huge' objects in the heap */ - hdr->id_len = 1 + hdr->sizeof_size + hdr->sizeof_addr; + case 1: /* Set the length of heap IDs to just enough to hold the information needed to directly access 'huge' objects in the heap */ + if(hdr->filter_len > 0) + hdr->id_len = 1 /* ID flags */ + + hdr->sizeof_addr /* Address of filtered object */ + + hdr->sizeof_size /* Length of filtered object */ + + 4 /* Filter mask for filtered object */ + + hdr->sizeof_size; /* Size of de-filtered object in memory */ + else + hdr->id_len = 1 /* ID flags */ + + hdr->sizeof_addr /* Address of object */ + + hdr->sizeof_size; /* Length of object */ break; default: /* Use the requested size for the heap ID */ -/* XXX: Limit heap ID length to 4096 + 1, due to # of bits required to store - * length of 'tiny' objects (12 bits) - */ -HDfprintf(stderr, "%s: Varying size of heap IDs not supported yet!\n", FUNC); -HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, HADDR_UNDEF, "varying size of heap IDs not supported yet") + /* Check boundaries */ + if(cparam->id_len < (1 + hdr->heap_off_size + hdr->heap_len_size)) + HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, HADDR_UNDEF, "ID length not large enough to hold object IDs") + else if(cparam->id_len > H5HF_MAX_ID_LEN) + HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, HADDR_UNDEF, "ID length too large to store tiny object lengths") + + /* Use the requested size for the heap ID */ + hdr->id_len = cparam->id_len; break; } /* end switch */ +#ifdef QAK +HDfprintf(stderr, "%s: hdr->id_len = %Zu\n", FUNC, hdr->id_len); +#endif /* QAK */ /* Second phase of header final initialization */ + /* (needs ID and filter lengths set up) */ if(H5HF_hdr_finish_init_phase2(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't finish phase #2 of header final initialization") -#ifdef QAK -HDfprintf(stderr, "%s: hdr->id_len = %Zu\n", FUNC, hdr->id_len); -#endif /* QAK */ - /* Extra checking for possible gap between max. direct block size minus * overhead and "huge" object size */ dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr); if((cparam->managed.max_direct_size - dblock_overhead) < cparam->max_man_size) HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, HADDR_UNDEF, "max. direct block size not large enough to hold all managed blocks") + /* Allocate space for the header on disk */ + if(HADDR_UNDEF == (hdr->heap_addr = H5MF_alloc(f, H5FD_MEM_FHEAP_HDR, dxpl_id, (hsize_t)hdr->heap_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for fractal heap header") + /* Cache the new fractal heap header */ - if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't add fractal heap header to cache") /* Set address of heap header to return */ - ret_value = hdr_addr; + ret_value = hdr->heap_addr; done: if(!H5F_addr_defined(ret_value)) |