1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /*-------------------------------------------------------------------------
15 *
16 * Created: H5HFhuge.c
17 * Aug 7 2006
18 * Quincey Koziol <koziol@hdfgroup.org>
19 *
20 * Purpose: Routines for "huge" objects in fractal heap
21 *
22 *-------------------------------------------------------------------------
23 */
24
25 /****************/
26 /* Module Setup */
27 /****************/
28
29 #include "H5HFmodule.h" /* This source code file is part of the H5HF module */
30
31
32 /***********/
33 /* Headers */
34 /***********/
35 #include "H5private.h" /* Generic Functions */
36 #include "H5Eprivate.h" /* Error handling */
37 #include "H5HFpkg.h" /* Fractal heaps */
38 #include "H5MFprivate.h" /* File memory management */
39 #include "H5MMprivate.h" /* Memory management */
40
41
42 /****************/
43 /* Local Macros */
44 /****************/
45
46 /* v2 B-tree creation macros */
47 #define H5HF_HUGE_BT2_NODE_SIZE 512
48 #define H5HF_HUGE_BT2_SPLIT_PERC 100
49 #define H5HF_HUGE_BT2_MERGE_PERC 40
50
51
52 /******************/
53 /* Local Typedefs */
54 /******************/
55
56
57 /********************/
58 /* Package Typedefs */
59 /********************/
60
61
62 /********************/
63 /* Local Prototypes */
64 /********************/
65
66 /* Local v2 B-tree operations */
67 static herr_t H5HF_huge_bt2_create(H5HF_hdr_t *hdr, hid_t dxpl_id);
68
69 /* Local 'huge' object support routines */
70 static hsize_t H5HF_huge_new_id(H5HF_hdr_t *hdr);
71 static herr_t H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id,
72 const uint8_t *id, hbool_t is_read, H5HF_operator_t op, void *op_data);
73
74
75 /*********************/
76 /* Package Variables */
77 /*********************/
78
79
80 /*****************************/
81 /* Library Private Variables */
82 /*****************************/
83
84
85 /*******************/
86 /* Local Variables */
87 /*******************/
88
89
90 /*-------------------------------------------------------------------------
91 * Function: H5HF_huge_bt2_create
92 *
93 * Purpose: Create the v2 B-tree for tracking the huge objects in the heap
94 *
95 * Return: SUCCEED/FAIL
96 *
97 * Programmer: Quincey Koziol
98 * koziol@hdfgroup.org
99 * Aug 7 2006
100 *
101 *-------------------------------------------------------------------------
102 */
103 static herr_t
H5HF_huge_bt2_create(H5HF_hdr_t * hdr,hid_t dxpl_id)104 H5HF_huge_bt2_create(H5HF_hdr_t *hdr, hid_t dxpl_id)
105 {
106 H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */
107 herr_t ret_value = SUCCEED; /* Return value */
108
109 FUNC_ENTER_NOAPI_NOINIT
110
111 /*
112 * Check arguments.
113 */
114 HDassert(hdr);
115
116 /* Compute the size of 'raw' records on disk */
117 /* (Note: the size for huge IDs could be set to 'huge_id_size', instead
118 * of 'sizeof_size', but that would make the v2 B-tree callback routines
119 * depend on the heap header, which makes the v2 B-tree flush routines
120 * difficult to write. "Waste" an extra byte or for small heaps (where
121 * the 'huge_id_size' is < 'sizeof_size' in order to make this easier -QAK)
122 */
123 if(hdr->huge_ids_direct) {
124 if(hdr->filter_len > 0) {
125 bt2_cparam.rrec_size = (size_t)((unsigned)hdr->sizeof_addr /* Address of object */
126 + (unsigned)hdr->sizeof_size /* Length of object */
127 + (unsigned)4 /* Filter mask for filtered object */
128 + (unsigned)hdr->sizeof_size); /* Size of de-filtered object in memory */
129 bt2_cparam.cls = H5HF_HUGE_BT2_FILT_DIR;
130 } /* end if */
131 else {
132 bt2_cparam.rrec_size = (size_t)((unsigned)hdr->sizeof_addr /* Address of object */
133 + (unsigned)hdr->sizeof_size); /* Length of object */
134 bt2_cparam.cls = H5HF_HUGE_BT2_DIR;
135 } /* end else */
136 } /* end if */
137 else {
138 if(hdr->filter_len > 0) {
139 bt2_cparam.rrec_size = (size_t)((unsigned)hdr->sizeof_addr /* Address of filtered object */
140 + (unsigned)hdr->sizeof_size /* Length of filtered object */
141 + (unsigned)4 /* Filter mask for filtered object */
142 + (unsigned)hdr->sizeof_size /* Size of de-filtered object in memory */
143 + (unsigned)hdr->sizeof_size); /* Unique ID for object */
144 bt2_cparam.cls = H5HF_HUGE_BT2_FILT_INDIR;
145 } /* end if */
146 else {
147 bt2_cparam.rrec_size = (size_t)((unsigned)hdr->sizeof_addr /* Address of object */
148 + (unsigned)hdr->sizeof_size /* Length of object */
149 + (unsigned)hdr->sizeof_size); /* Unique ID for object */
150 bt2_cparam.cls = H5HF_HUGE_BT2_INDIR;
151 } /* end else */
152 } /* end else */
153 bt2_cparam.node_size = (size_t)H5HF_HUGE_BT2_NODE_SIZE;
154 bt2_cparam.split_percent = H5HF_HUGE_BT2_SPLIT_PERC;
155 bt2_cparam.merge_percent = H5HF_HUGE_BT2_MERGE_PERC;
156
157 /* Create v2 B-tree for tracking 'huge' objects */
158 if(NULL == (hdr->huge_bt2 = H5B2_create(hdr->f, dxpl_id, &bt2_cparam, hdr->f)))
159 HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create v2 B-tree for tracking 'huge' heap objects")
160
161 /* Retrieve the v2 B-tree's address in the file */
162 if(H5B2_get_addr(hdr->huge_bt2, &hdr->huge_bt2_addr) < 0)
163 HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get v2 B-tree address for tracking 'huge' heap objects")
164
165 done:
166 FUNC_LEAVE_NOAPI(ret_value)
167 } /* end H5HF_huge_bt2_create() */
168
169
170 /*-------------------------------------------------------------------------
171 * Function: H5HF_huge_init
172 *
173 * Purpose: Initialize information for tracking 'huge' objects
174 *
175 * Return: SUCCEED/FAIL
176 *
177 * Programmer: Quincey Koziol
178 * koziol@hdfgroup.org
179 * Aug 7 2006
180 *
181 *-------------------------------------------------------------------------
182 */
183 herr_t
H5HF_huge_init(H5HF_hdr_t * hdr)184 H5HF_huge_init(H5HF_hdr_t *hdr)
185 {
186 FUNC_ENTER_NOAPI_NOINIT_NOERR
187
188 /*
189 * Check arguments.
190 */
191 HDassert(hdr);
192
193 /* Compute information about 'huge' objects for the heap */
194
195 /* Check if we can completely hold the 'huge' object's offset & length in
196 * the file in the heap ID (which will speed up accessing it) and we don't
197 * have any I/O pipeline filters.
198 */
199 #ifdef QAK
200 HDfprintf(stderr, "%s: hdr->id_len = %u\n", "H5HF_huge_init", (unsigned)hdr->id_len);
201 HDfprintf(stderr, "%s: hdr->filter_len = %u\n", "H5HF_huge_init", (unsigned)hdr->filter_len);
202 #endif /* QAK */
203 if(hdr->filter_len > 0) {
204 if((hdr->id_len - 1) >= (unsigned)(hdr->sizeof_addr + hdr->sizeof_size + 4 + hdr->sizeof_size)) {
205 /* Indicate that v2 B-tree doesn't have to be used to locate object */
206 hdr->huge_ids_direct = TRUE;
207
208 /* Set the size of 'huge' object IDs */
209 hdr->huge_id_size = (uint8_t)(hdr->sizeof_addr + hdr->sizeof_size + hdr->sizeof_size);
210 } /* end if */
211 else
212 /* Indicate that v2 B-tree must be used to access object */
213 hdr->huge_ids_direct = FALSE;
214 } /* end if */
215 else {
216 if((hdr->sizeof_addr + hdr->sizeof_size) <= (hdr->id_len - 1)) {
217 /* Indicate that v2 B-tree doesn't have to be used to locate object */
218 hdr->huge_ids_direct = TRUE;
219
220 /* Set the size of 'huge' object IDs */
221 hdr->huge_id_size = (uint8_t)(hdr->sizeof_addr + hdr->sizeof_size);
222 } /* end if */
223 else
224 /* Indicate that v2 B-tree must be used to locate object */
225 hdr->huge_ids_direct = FALSE;
226 } /* end else */
227 if(!hdr->huge_ids_direct) {
228 /* Set the size and maximum value of 'huge' object ID */
229 if((hdr->id_len - 1) < sizeof(hsize_t)) {
230 hdr->huge_id_size = (uint8_t)(hdr->id_len - 1);
231 hdr->huge_max_id = ((hsize_t)1 << (hdr->huge_id_size * 8)) - 1;
232 } /*end if */
233 else {
234 hdr->huge_id_size = sizeof(hsize_t);
235 hdr->huge_max_id = HSIZET_MAX;
236 } /* end else */
237 } /* end if */
238 hdr->huge_bt2 = NULL;
239
240 FUNC_LEAVE_NOAPI(SUCCEED)
241 } /* end H5HF_huge_init() */
242
243
244 /*-------------------------------------------------------------------------
245 * Function: H5HF_huge_new_id
246 *
247 * Purpose: Determine a new ID for an indirectly accessed 'huge' object
248 * (either filtered or not)
249 *
250 * Return: SUCCEED/FAIL
251 *
252 * Programmer: Quincey Koziol
253 * koziol@hdfgroup.org
254 * Aug 15 2006
255 *
256 *-------------------------------------------------------------------------
257 */
258 static hsize_t
H5HF_huge_new_id(H5HF_hdr_t * hdr)259 H5HF_huge_new_id(H5HF_hdr_t *hdr)
260 {
261 hsize_t new_id; /* New object's ID */
262 hsize_t ret_value = 0; /* Return value */
263
264 FUNC_ENTER_NOAPI_NOINIT
265
266 /*
267 * Check arguments.
268 */
269 HDassert(hdr);
270
271 /* Check for wrapping around 'huge' object ID space */
272 if(hdr->huge_ids_wrapped)
273 /* Fail for now - eventually should iterate through v2 B-tree, looking for available ID */
274 HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, 0, "wrapping 'huge' object IDs not supported yet")
275 else {
276 /* Get new 'huge' object ID to use for object */
277 /* (avoids using ID 0) */
278 new_id = ++hdr->huge_next_id;
279
280 /* Check for wrapping 'huge' object IDs around */
281 if(hdr->huge_next_id == hdr->huge_max_id)
282 hdr->huge_ids_wrapped = TRUE;
283 } /* end else */
284
285 /* Set return value */
286 ret_value = new_id;
287
288 done:
289 FUNC_LEAVE_NOAPI(ret_value)
290 } /* end H5HF_huge_new_id() */
291
292
293 /*-------------------------------------------------------------------------
294 * Function: H5HF_huge_insert
295 *
296 * Purpose: Insert a 'huge' object into the file and track it
297 *
298 * Return: SUCCEED/FAIL
299 *
300 * Programmer: Quincey Koziol
301 * koziol@hdfgroup.org
302 * Aug 7 2006
303 *
304 *-------------------------------------------------------------------------
305 */
306 herr_t
H5HF_huge_insert(H5HF_hdr_t * hdr,hid_t dxpl_id,size_t obj_size,void * obj,void * _id)307 H5HF_huge_insert(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t obj_size, void *obj,
308 void *_id)
309 {
310 uint8_t *id = (uint8_t *)_id; /* Pointer to ID buffer */
311 haddr_t obj_addr; /* Address of object in the file */
312 void *write_buf; /* Pointer to buffer to write */
313 size_t write_size; /* Size of [possibly filtered] object written to file */
314 unsigned filter_mask = 0; /* Filter mask for object (only used for filtered objects) */
315 herr_t ret_value = SUCCEED; /* Return value */
316
317 FUNC_ENTER_NOAPI_NOINIT
318 #ifdef QAK
319 HDfprintf(stderr, "%s: obj_size = %Zu\n", FUNC, obj_size);
320 #endif /* QAK */
321
322 /*
323 * Check arguments.
324 */
325 HDassert(hdr);
326 HDassert(obj_size > hdr->max_man_size);
327 HDassert(obj);
328 HDassert(id);
329
330 /* Check if the v2 B-tree for tracking 'huge' heap objects has been created yet */
331 if(!H5F_addr_defined(hdr->huge_bt2_addr)) {
332 /* Go create (& open) v2 B-tree */
333 if(H5HF_huge_bt2_create(hdr, dxpl_id) < 0)
334 HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create v2 B-tree for tracking 'huge' heap objects")
335 } /* end if */
336 else {
337 /* Check if v2 B-tree is open yet */
338 if(NULL == hdr->huge_bt2) {
339 /* Open existing v2 B-tree */
340 if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f)))
341 HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects")
342 } /* end if */
343 } /* end else */
344 HDassert(hdr->huge_bt2);
345
346 /* Check for I/O pipeline filter on heap */
347 if(hdr->filter_len > 0) {
348 H5Z_cb_t filter_cb = {NULL, NULL}; /* Filter callback structure */
349 size_t nbytes; /* Number of bytes used */
350
351 /* Allocate buffer to perform I/O filtering on */
352 write_size = obj_size;
353 if(NULL == (write_buf = H5MM_malloc(write_size)))
354 HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline buffer")
355 HDmemcpy(write_buf, obj, write_size);
356
357 /* Push direct block data through I/O filter pipeline */
358 nbytes = write_size;
359 if(H5Z_pipeline(&(hdr->pline), 0, &filter_mask, H5Z_NO_EDC,
360 filter_cb, &nbytes, &write_size, &write_buf) < 0)
361 HGOTO_ERROR(H5E_HEAP, H5E_CANTFILTER, FAIL, "output pipeline failed")
362 #ifdef QAK
363 HDfprintf(stderr, "%s: nbytes = %Zu, write_size = %Zu, write_buf = %p\n", FUNC, nbytes, write_size, write_buf);
364 HDfprintf(stderr, "%s: obj_size = %Zu, obj = %p\n", FUNC, obj_size, obj);
365 #endif /* QAK */
366
367 /* Update size of object on disk */
368 write_size = nbytes;
369 } /* end if */
370 else {
371 write_buf = obj;
372 write_size = obj_size;
373 } /* end else */
374
375 /* Allocate space in the file for storing the 'huge' object */
376 if(HADDR_UNDEF == (obj_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, dxpl_id, (hsize_t)write_size)))
377 HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap huge object")
378
379 /* Write the object's data to disk */
380 if(H5F_block_write(hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, obj_addr, write_size, H5AC_rawdata_dxpl_id, write_buf) < 0)
381 HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "writing 'huge' object to file failed")
382
383 /* Release buffer for writing, if we had one */
384 if(write_buf != obj) {
385 HDassert(hdr->filter_len > 0);
386 H5MM_xfree(write_buf);
387 } /* end if */
388
389 /* Perform different actions for directly & indirectly accessed 'huge' objects */
390 if(hdr->huge_ids_direct) {
391 if(hdr->filter_len > 0) {
392 H5HF_huge_bt2_filt_dir_rec_t obj_rec; /* Record for tracking object */
393
394 /* Initialize record for tracking object in v2 B-tree */
395 obj_rec.addr = obj_addr;
396 obj_rec.len = write_size;
397 obj_rec.filter_mask = filter_mask;
398 obj_rec.obj_size = obj_size;
399 #ifdef QAK
400 HDfprintf(stderr, "%s: obj_rec = {%a, %Hu, %x, %Hu}\n", FUNC, obj_rec.addr, obj_rec.len, obj_rec.filter_mask, obj_rec.obj_size);
401 #endif /* QAK */
402
403 /* Insert record for object in v2 B-tree */
404 if(H5B2_insert(hdr->huge_bt2, dxpl_id, &obj_rec) < 0)
405 HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree")
406
407 /* Encode ID for user */
408 *id++ = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_HUGE;
409 H5F_addr_encode(hdr->f, &id, obj_addr);
410 H5F_ENCODE_LENGTH(hdr->f, id, (hsize_t)write_size);
411 UINT32ENCODE(id, filter_mask);
412 H5F_ENCODE_LENGTH(hdr->f, id, (hsize_t)obj_size);
413 } /* end if */
414 else {
415 H5HF_huge_bt2_dir_rec_t obj_rec; /* Record for tracking object */
416
417 /* Initialize record for tracking object in v2 B-tree */
418 obj_rec.addr = obj_addr;
419 obj_rec.len = write_size;
420 #ifdef QAK
421 HDfprintf(stderr, "%s: obj_rec = {%a, %Hu}\n", FUNC, obj_rec.addr, obj_rec.len);
422 #endif /* QAK */
423
424 /* Insert record for object in v2 B-tree */
425 if(H5B2_insert(hdr->huge_bt2, dxpl_id, &obj_rec) < 0)
426 HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree")
427
428 /* Encode ID for user */
429 *id++ = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_HUGE;
430 H5F_addr_encode(hdr->f, &id, obj_addr);
431 H5F_ENCODE_LENGTH(hdr->f, id, (hsize_t)write_size);
432 } /* end if */
433 } /* end if */
434 else {
435 H5HF_huge_bt2_filt_indir_rec_t filt_indir_rec; /* Record for tracking filtered object */
436 H5HF_huge_bt2_indir_rec_t indir_rec; /* Record for tracking non-filtered object */
437 void *ins_rec; /* Pointer to record to insert */
438 hsize_t new_id; /* New ID for object */
439
440 /* Get new ID for object */
441 if(0 == (new_id = H5HF_huge_new_id(hdr)))
442 HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't generate new ID for object")
443
444 if(hdr->filter_len > 0) {
445 /* Initialize record for object in v2 B-tree */
446 filt_indir_rec.addr = obj_addr;
447 filt_indir_rec.len = write_size;
448 filt_indir_rec.filter_mask = filter_mask;
449 filt_indir_rec.obj_size = obj_size;
450 filt_indir_rec.id = new_id;
451 #ifdef QAK
452 HDfprintf(stderr, "%s: filt_indir_rec = {%a, %Hu, %x, %Hu, %Hu}\n", FUNC, filt_indir_rec.addr, filt_indir_rec.len, filt_indir_rec.filter_mask, filt_indir_rec.obj_size, filt_indir_rec.id);
453 #endif /* QAK */
454
455 /* Set pointer to record to insert */
456 ins_rec = &filt_indir_rec;
457 } /* end if */
458 else {
459 /* Initialize record for object in v2 B-tree */
460 indir_rec.addr = obj_addr;
461 indir_rec.len = write_size;
462 indir_rec.id = new_id;
463 #ifdef QAK
464 HDfprintf(stderr, "%s: indir_rec = {%a, %Hu, %Hu}\n", FUNC, indir_rec.addr, indir_rec.len, indir_rec.id);
465 #endif /* QAK */
466
467 /* Set pointer to record to insert */
468 ins_rec = &indir_rec;
469 } /* end else */
470
471 /* Insert record for tracking object in v2 B-tree */
472 if(H5B2_insert(hdr->huge_bt2, dxpl_id, ins_rec) < 0)
473 HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree")
474
475 /* Encode ID for user */
476 *id++ = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_HUGE;
477 UINT64ENCODE_VAR(id, new_id, hdr->huge_id_size)
478 } /* end else */
479
480 /* Update statistics about heap */
481 hdr->huge_size += obj_size;
482 hdr->huge_nobjs++;
483
484 /* Mark heap header as modified */
485 if(H5HF_hdr_dirty(hdr) < 0)
486 HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
487
488 done:
489 FUNC_LEAVE_NOAPI(ret_value)
490 } /* end H5HF_huge_insert() */
491
492
493 /*-------------------------------------------------------------------------
494 * Function: H5HF_huge_get_obj_len
495 *
496 * Purpose: Get the size of a 'huge' object in a fractal heap
497 *
498 * Return: SUCCEED/FAIL
499 *
500 * Programmer: Quincey Koziol
501 * koziol@hdfgroup.org
502 * Aug 8 2006
503 *
504 *-------------------------------------------------------------------------
505 */
506 herr_t
H5HF_huge_get_obj_len(H5HF_hdr_t * hdr,hid_t dxpl_id,const uint8_t * id,size_t * obj_len_p)507 H5HF_huge_get_obj_len(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
508 size_t *obj_len_p)
509 {
510 herr_t ret_value = SUCCEED; /* Return value */
511
512 FUNC_ENTER_NOAPI_NOINIT
513
514 /*
515 * Check arguments.
516 */
517 HDassert(hdr);
518 HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
519 HDassert(id);
520 HDassert(obj_len_p);
521
522 /* Skip over the flag byte */
523 id++;
524
525 /* Check if 'huge' object ID encodes address & length directly */
526 if(hdr->huge_ids_direct) {
527 if(hdr->filter_len > 0) {
528 /* Skip over filtered object info */
529 id += hdr->sizeof_addr + hdr->sizeof_size + 4;
530
531 /* Retrieve the object's length */
532 H5F_DECODE_LENGTH(hdr->f, id, *obj_len_p);
533 } /* end if */
534 else {
535 /* Skip over object offset in file */
536 id += hdr->sizeof_addr;
537
538 /* Retrieve the object's length */
539 H5F_DECODE_LENGTH(hdr->f, id, *obj_len_p);
540 } /* end else */
541 } /* end if */
542 else {
543 /* Check if v2 B-tree is open yet */
544 if(NULL == hdr->huge_bt2) {
545 /* Open existing v2 B-tree */
546 if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f)))
547 HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects")
548 } /* end if */
549
550 if(hdr->filter_len > 0) {
551 H5HF_huge_bt2_filt_indir_rec_t found_rec; /* Record found from tracking object */
552 H5HF_huge_bt2_filt_indir_rec_t search_rec; /* Record for searching for object */
553
554 /* Get ID for looking up 'huge' object in v2 B-tree */
555 UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
556
557 /* Look up object in v2 B-tree */
558 if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF__huge_bt2_filt_indir_found, &found_rec) != TRUE)
559 HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree")
560
561 /* Retrieve the object's length */
562 *obj_len_p = (size_t)found_rec.obj_size;
563 } /* end if */
564 else {
565 H5HF_huge_bt2_indir_rec_t found_rec; /* Record found from tracking object */
566 H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */
567
568 /* Get ID for looking up 'huge' object in v2 B-tree */
569 UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
570
571 /* Look up object in v2 B-tree */
572 if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF__huge_bt2_indir_found, &found_rec) != TRUE)
573 HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree")
574
575 /* Retrieve the object's length */
576 *obj_len_p = (size_t)found_rec.len;
577 } /* end else */
578 } /* end else */
579
580 done:
581 FUNC_LEAVE_NOAPI(ret_value)
582 } /* end H5HF_huge_get_obj_len() */
583
584
585 /*-------------------------------------------------------------------------
586 * Function: H5HF__huge_get_obj_off
587 *
588 * Purpose: Get the offset of a 'huge' object in a fractal heap
589 *
590 * Return: SUCCEED/FAIL
591 *
592 * Programmer: Quincey Koziol
593 * koziol@hdfgroup.org
594 * Aug 8 2006
595 *
596 *-------------------------------------------------------------------------
597 */
598 herr_t
H5HF__huge_get_obj_off(H5HF_hdr_t * hdr,hid_t dxpl_id,const uint8_t * id,hsize_t * obj_off_p)599 H5HF__huge_get_obj_off(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
600 hsize_t *obj_off_p)
601 {
602 haddr_t obj_addr; /* Object's address in the file */
603 herr_t ret_value = SUCCEED; /* Return value */
604
605 FUNC_ENTER_NOAPI_NOINIT
606
607 /*
608 * Check arguments.
609 */
610 HDassert(hdr);
611 HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
612 HDassert(id);
613 HDassert(obj_off_p);
614
615 /* Skip over the flag byte */
616 id++;
617
618 /* Check if 'huge' object ID encodes address & length directly */
619 if(hdr->huge_ids_direct) {
620 /* Retrieve the object's address (common) */
621 H5F_addr_decode(hdr->f, &id, &obj_addr);
622 } /* end if */
623 else {
624 /* Sanity check */
625 HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
626
627 /* Check if v2 B-tree is open yet */
628 if(NULL == hdr->huge_bt2) {
629 /* Open existing v2 B-tree */
630 if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f)))
631 HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects")
632 } /* end if */
633
634 if(hdr->filter_len > 0) {
635 H5HF_huge_bt2_filt_indir_rec_t found_rec; /* Record found from tracking object */
636 H5HF_huge_bt2_filt_indir_rec_t search_rec; /* Record for searching for object */
637
638 /* Get ID for looking up 'huge' object in v2 B-tree */
639 UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
640
641 /* Look up object in v2 B-tree */
642 if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF__huge_bt2_filt_indir_found, &found_rec) != TRUE)
643 HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree")
644
645 /* Retrieve the object's address & length */
646 obj_addr = found_rec.addr;
647 } /* end if */
648 else {
649 H5HF_huge_bt2_indir_rec_t found_rec; /* Record found from tracking object */
650 H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */
651
652 /* Get ID for looking up 'huge' object in v2 B-tree */
653 UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
654
655 /* Look up object in v2 B-tree */
656 if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF__huge_bt2_indir_found, &found_rec) != TRUE)
657 HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree")
658
659 /* Retrieve the object's address & length */
660 obj_addr = found_rec.addr;
661 } /* end else */
662 } /* end else */
663
664 /* Set the value to return */
665 *obj_off_p = (hsize_t)obj_addr;
666
667 done:
668 FUNC_LEAVE_NOAPI(ret_value)
669 } /* end H5HF__huge_get_obj_off() */
670
671
672 /*-------------------------------------------------------------------------
673 * Function: H5HF_huge_op_real
674 *
675 * Purpose: Internal routine to perform an operation on a 'huge' object
676 *
677 * Return: SUCCEED/FAIL
678 *
679 * Programmer: Quincey Koziol
680 * koziol@hdfgroup.org
681 * Aug 8 2006
682 *
683 *-------------------------------------------------------------------------
684 */
685 static herr_t
H5HF_huge_op_real(H5HF_hdr_t * hdr,hid_t dxpl_id,const uint8_t * id,hbool_t is_read,H5HF_operator_t op,void * op_data)686 H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
687 hbool_t is_read, H5HF_operator_t op, void *op_data)
688 {
689 void *read_buf = NULL; /* Pointer to buffer for reading */
690 haddr_t obj_addr; /* Object's address in the file */
691 size_t obj_size = 0; /* Object's size in the file */
692 unsigned filter_mask = 0; /* Filter mask for object (only used for filtered objects) */
693 herr_t ret_value = SUCCEED; /* Return value */
694
695 FUNC_ENTER_NOAPI_NOINIT
696
697 /*
698 * Check arguments.
699 */
700 HDassert(hdr);
701 HDassert(id);
702 HDassert(is_read || op);
703
704 /* Skip over the flag byte */
705 id++;
706
707 /* Check for 'huge' object ID that encodes address & length directly */
708 if(hdr->huge_ids_direct) {
709 /* Retrieve the object's address and length (common) */
710 H5F_addr_decode(hdr->f, &id, &obj_addr);
711 H5F_DECODE_LENGTH(hdr->f, id, obj_size);
712
713 /* Retrieve extra information needed for filtered objects */
714 if(hdr->filter_len > 0)
715 UINT32DECODE(id, filter_mask);
716 } /* end if */
717 else {
718 /* Sanity check */
719 HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
720
721 /* Check if v2 B-tree is open yet */
722 if(NULL == hdr->huge_bt2) {
723 /* Open existing v2 B-tree */
724 if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f)))
725 HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects")
726 } /* end if */
727
728 if(hdr->filter_len > 0) {
729 H5HF_huge_bt2_filt_indir_rec_t found_rec; /* Record found from tracking object */
730 H5HF_huge_bt2_filt_indir_rec_t search_rec; /* Record for searching for object */
731
732 /* Get ID for looking up 'huge' object in v2 B-tree */
733 UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
734
735 /* Look up object in v2 B-tree */
736 if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF__huge_bt2_filt_indir_found, &found_rec) != TRUE)
737 HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree")
738
739 /* Retrieve the object's address & length */
740 obj_addr = found_rec.addr;
741 H5_CHECKED_ASSIGN(obj_size, size_t, found_rec.len, hsize_t);
742 filter_mask = found_rec.filter_mask;
743 } /* end if */
744 else {
745 H5HF_huge_bt2_indir_rec_t found_rec; /* Record found from tracking object */
746 H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */
747
748 /* Get ID for looking up 'huge' object in v2 B-tree */
749 UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
750
751 /* Look up object in v2 B-tree */
752 if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF__huge_bt2_indir_found, &found_rec) != TRUE)
753 HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree")
754
755 /* Retrieve the object's address & length */
756 obj_addr = found_rec.addr;
757 H5_CHECKED_ASSIGN(obj_size, size_t, found_rec.len, hsize_t);
758 } /* end else */
759 } /* end else */
760
761 /* Set up buffer for reading */
762 if(hdr->filter_len > 0 || !is_read) {
763 if(NULL == (read_buf = H5MM_malloc((size_t)obj_size)))
764 HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline buffer")
765 } /* end if */
766 else
767 read_buf = op_data;
768
769 /* Read the object's (possibly filtered) data from the file */
770 /* (reads directly into application's buffer if no filters are present) */
771 if(H5F_block_read(hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, obj_addr, (size_t)obj_size, H5AC_rawdata_dxpl_id, read_buf) < 0)
772 HGOTO_ERROR(H5E_HEAP, H5E_READERROR, FAIL, "can't read 'huge' object's data from the file")
773
774 /* Check for I/O pipeline filter on heap */
775 if(hdr->filter_len > 0) {
776 H5Z_cb_t filter_cb = {NULL, NULL}; /* Filter callback structure */
777 size_t read_size; /* Object's size in the file */
778 size_t nbytes; /* Number of bytes used */
779
780 /* De-filter the object */
781 read_size = nbytes = obj_size;
782 if(H5Z_pipeline(&(hdr->pline), H5Z_FLAG_REVERSE, &filter_mask, H5Z_NO_EDC, filter_cb, &nbytes, &read_size, &read_buf) < 0)
783 HGOTO_ERROR(H5E_HEAP, H5E_CANTFILTER, FAIL, "input filter failed")
784 obj_size = nbytes;
785 } /* end if */
786
787 /* Perform correct operation on buffer read in */
788 if(is_read) {
789 /* Copy object to user's buffer if there's filters on heap data */
790 /* (if there's no filters, the object was read directly into the user's buffer) */
791 if(hdr->filter_len > 0)
792 HDmemcpy(op_data, read_buf, (size_t)obj_size);
793 } /* end if */
794 else {
795 /* Call the user's 'op' callback */
796 if(op(read_buf, (size_t)obj_size, op_data) < 0) {
797 /* Release buffer */
798 read_buf = H5MM_xfree(read_buf);
799
800 /* Indicate error */
801 HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "application's callback failed")
802 } /* end if */
803 } /* end if */
804
805 done:
806 /* Release the buffer for reading */
807 if(read_buf && read_buf != op_data)
808 read_buf = H5MM_xfree(read_buf);
809
810 FUNC_LEAVE_NOAPI(ret_value)
811 } /* end H5HF_huge_op_real() */
812
813
814 /*-------------------------------------------------------------------------
815 * Function: H5HF_huge_write
816 *
817 * Purpose: Write a 'huge' object to the heap
818 *
819 * Note: This implementation somewhat limited: it doesn't handle
820 * heaps with filters, which would require re-compressing the
821 * huge object and probably changing the address of the object
822 * on disk (and possibly the heap ID for "direct" huge IDs).
823 *
824 * Return: SUCCEED/FAIL
825 *
826 * Programmer: Quincey Koziol
827 * koziol@hdfgroup.org
828 * Feb 21 2007
829 *
830 *-------------------------------------------------------------------------
831 */
832 herr_t
H5HF_huge_write(H5HF_hdr_t * hdr,hid_t dxpl_id,const uint8_t * id,const void * obj)833 H5HF_huge_write(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
834 const void *obj)
835 {
836 haddr_t obj_addr; /* Object's address in the file */
837 size_t obj_size; /* Object's size in the file */
838 herr_t ret_value = SUCCEED; /* Return value */
839
840 FUNC_ENTER_NOAPI_NOINIT
841
842 /*
843 * Check arguments.
844 */
845 HDassert(hdr);
846 HDassert(id);
847 HDassert(obj);
848
849 /* Check for filters on the heap */
850 if(hdr->filter_len > 0)
851 HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "modifying 'huge' object with filters not supported yet")
852
853 /* Skip over the flag byte */
854 id++;
855
856 /* Check for 'huge' object ID that encodes address & length directly */
857 if(hdr->huge_ids_direct) {
858 /* Retrieve the object's address and length (common) */
859 H5F_addr_decode(hdr->f, &id, &obj_addr);
860 H5F_DECODE_LENGTH(hdr->f, id, obj_size);
861 } /* end if */
862 else {
863 H5HF_huge_bt2_indir_rec_t found_rec; /* Record found from tracking object */
864 H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */
865
866 /* Sanity check */
867 HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
868
869 /* Check if v2 B-tree is open yet */
870 if(NULL == hdr->huge_bt2) {
871 /* Open existing v2 B-tree */
872 if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f)))
873 HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects")
874 } /* end if */
875
876 /* Get ID for looking up 'huge' object in v2 B-tree */
877 UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
878
879 /* Look up object in v2 B-tree */
880 if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF__huge_bt2_indir_found, &found_rec) != TRUE)
881 HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree")
882
883 /* Retrieve the object's address & length */
884 obj_addr = found_rec.addr;
885 H5_CHECKED_ASSIGN(obj_size, size_t, found_rec.len, hsize_t);
886 } /* end else */
887
888 /* Write the object's data to the file */
889 /* (writes directly from application's buffer) */
890 if(H5F_block_write(hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, obj_addr, obj_size, H5AC_rawdata_dxpl_id, obj) < 0)
891 HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "writing 'huge' object to file failed")
892
893 done:
894 FUNC_LEAVE_NOAPI(ret_value)
895 } /* end H5HF_huge_write() */
896
897
898 /*-------------------------------------------------------------------------
899 * Function: H5HF_huge_read
900 *
901 * Purpose: Read a 'huge' object from the heap
902 *
903 * Return: SUCCEED/FAIL
904 *
905 * Programmer: Quincey Koziol
906 * koziol@ncsa.uiuc.edu
907 * Sept 11 2006
908 *
909 *-------------------------------------------------------------------------
910 */
911 herr_t
H5HF_huge_read(H5HF_hdr_t * hdr,hid_t dxpl_id,const uint8_t * id,void * obj)912 H5HF_huge_read(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, void *obj)
913 {
914 herr_t ret_value = SUCCEED; /* Return value */
915
916 FUNC_ENTER_NOAPI_NOINIT
917
918 /*
919 * Check arguments.
920 */
921 HDassert(hdr);
922 HDassert(id);
923 HDassert(obj);
924
925 /* Call the internal 'op' routine */
926 if(H5HF_huge_op_real(hdr, dxpl_id, id, TRUE, NULL, obj) < 0)
927 HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "unable to operate on heap object")
928
929 done:
930 FUNC_LEAVE_NOAPI(ret_value)
931 } /* end H5HF_huge_read() */
932
933
934 /*-------------------------------------------------------------------------
935 * Function: H5HF_huge_op
936 *
937 * Purpose: Operate directly on a 'huge' object
938 *
939 * Return: SUCCEED/FAIL
940 *
941 * Programmer: Quincey Koziol
942 * koziol@ncsa.uiuc.edu
943 * Sept 11 2006
944 *
945 *-------------------------------------------------------------------------
946 */
947 herr_t
H5HF_huge_op(H5HF_hdr_t * hdr,hid_t dxpl_id,const uint8_t * id,H5HF_operator_t op,void * op_data)948 H5HF_huge_op(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
949 H5HF_operator_t op, void *op_data)
950 {
951 herr_t ret_value = SUCCEED; /* Return value */
952
953 FUNC_ENTER_NOAPI_NOINIT
954
955 /*
956 * Check arguments.
957 */
958 HDassert(hdr);
959 HDassert(id);
960 HDassert(op);
961
962 /* Call the internal 'op' routine routine */
963 if(H5HF_huge_op_real(hdr, dxpl_id, id, FALSE, op, op_data) < 0)
964 HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "unable to operate on heap object")
965
966 done:
967 FUNC_LEAVE_NOAPI(ret_value)
968 } /* end H5HF_huge_op() */
969
970
971 /*-------------------------------------------------------------------------
972 * Function: H5HF_huge_remove
973 *
974 * Purpose: Remove a 'huge' object from the file and the v2 B-tree tracker
975 *
976 * Return: SUCCEED/FAIL
977 *
978 * Programmer: Quincey Koziol
979 * koziol@hdfgroup.org
980 * Aug 8 2006
981 *
982 *-------------------------------------------------------------------------
983 */
984 herr_t
H5HF_huge_remove(H5HF_hdr_t * hdr,hid_t dxpl_id,const uint8_t * id)985 H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id)
986 {
987 H5HF_huge_remove_ud_t udata; /* User callback data for v2 B-tree remove call */
988 herr_t ret_value = SUCCEED; /* Return value */
989
990 FUNC_ENTER_NOAPI_NOINIT
991
992 /*
993 * Check arguments.
994 */
995 HDassert(hdr);
996 HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
997 HDassert(id);
998
999 /* Check if v2 B-tree is open yet */
1000 if(NULL == hdr->huge_bt2) {
1001 /* Open existing v2 B-tree */
1002 if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f)))
1003 HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects")
1004 } /* end if */
1005
1006 /* Skip over the flag byte */
1007 id++;
1008
1009 /* Set up the common callback info */
1010 udata.hdr = hdr;
1011 udata.dxpl_id = dxpl_id;
1012
1013 /* Check for 'huge' object ID that encodes address & length directly */
1014 if(hdr->huge_ids_direct) {
1015 if(hdr->filter_len > 0) {
1016 H5HF_huge_bt2_filt_dir_rec_t search_rec; /* Record for searching for object */
1017
1018 /* Retrieve the object's address and length */
1019 /* (used as key in v2 B-tree record) */
1020 H5F_addr_decode(hdr->f, &id, &search_rec.addr);
1021 H5F_DECODE_LENGTH(hdr->f, id, search_rec.len);
1022
1023 /* Remove the record for tracking the 'huge' object from the v2 B-tree */
1024 /* (space in the file for the object is freed in the 'remove' callback) */
1025 if(H5B2_remove(hdr->huge_bt2, dxpl_id, &search_rec, H5HF__huge_bt2_filt_dir_remove, &udata) < 0)
1026 HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree")
1027 } /* end if */
1028 else {
1029 H5HF_huge_bt2_dir_rec_t search_rec; /* Record for searching for object */
1030
1031 /* Retrieve the object's address and length */
1032 /* (used as key in v2 B-tree record) */
1033 H5F_addr_decode(hdr->f, &id, &search_rec.addr);
1034 H5F_DECODE_LENGTH(hdr->f, id, search_rec.len);
1035
1036 /* Remove the record for tracking the 'huge' object from the v2 B-tree */
1037 /* (space in the file for the object is freed in the 'remove' callback) */
1038 if(H5B2_remove(hdr->huge_bt2, dxpl_id, &search_rec, H5HF__huge_bt2_dir_remove, &udata) < 0)
1039 HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree")
1040 } /* end else */
1041 } /* end if */
1042 else {
1043 if(hdr->filter_len > 0) {
1044 H5HF_huge_bt2_filt_indir_rec_t search_rec; /* Record for searching for object */
1045
1046 /* Get ID for looking up 'huge' object in v2 B-tree */
1047 UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
1048
1049 /* Remove the record for tracking the 'huge' object from the v2 B-tree */
1050 /* (space in the file for the object is freed in the 'remove' callback) */
1051 if(H5B2_remove(hdr->huge_bt2, dxpl_id, &search_rec, H5HF__huge_bt2_filt_indir_remove, &udata) < 0)
1052 HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree")
1053 } /* end if */
1054 else {
1055 H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */
1056
1057 /* Get ID for looking up 'huge' object in v2 B-tree */
1058 UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
1059
1060 /* Remove the record for tracking the 'huge' object from the v2 B-tree */
1061 /* (space in the file for the object is freed in the 'remove' callback) */
1062 if(H5B2_remove(hdr->huge_bt2, dxpl_id, &search_rec, H5HF__huge_bt2_indir_remove, &udata) < 0)
1063 HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree")
1064 } /* end else */
1065 } /* end else */
1066
1067 /* Update statistics about heap */
1068 hdr->huge_size -= udata.obj_len;
1069 hdr->huge_nobjs--;
1070
1071 /* Mark heap header as modified */
1072 if(H5HF_hdr_dirty(hdr) < 0)
1073 HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
1074
1075 done:
1076 FUNC_LEAVE_NOAPI(ret_value)
1077 } /* end H5HF_huge_remove() */
1078
1079
1080 /*-------------------------------------------------------------------------
1081 * Function: H5HF_huge_term
1082 *
1083 * Purpose: Shut down the information for tracking 'huge' objects
1084 *
1085 * Return: SUCCEED/FAIL
1086 *
1087 * Programmer: Quincey Koziol
1088 * koziol@hdfgroup.org
1089 * Aug 8 2006
1090 *
1091 *-------------------------------------------------------------------------
1092 */
1093 herr_t
H5HF_huge_term(H5HF_hdr_t * hdr,hid_t dxpl_id)1094 H5HF_huge_term(H5HF_hdr_t *hdr, hid_t dxpl_id)
1095 {
1096 herr_t ret_value = SUCCEED; /* Return value */
1097
1098 FUNC_ENTER_NOAPI_NOINIT
1099
1100 /*
1101 * Check arguments.
1102 */
1103 HDassert(hdr);
1104
1105 /* Check if v2 B-tree index is open */
1106 if(hdr->huge_bt2) {
1107 /* Sanity check */
1108 HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
1109
1110 /* Close v2 B-tree index */
1111 if(H5B2_close(hdr->huge_bt2, dxpl_id) < 0)
1112 HGOTO_ERROR(H5E_HEAP, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree")
1113 hdr->huge_bt2 = NULL;
1114 } /* end if */
1115
1116 /* Check if there are no more 'huge' objects in the heap and delete the
1117 * v2 B-tree that tracks them, if so
1118 */
1119 if(H5F_addr_defined(hdr->huge_bt2_addr) && hdr->huge_nobjs == 0) {
1120 /* Sanity check */
1121 HDassert(hdr->huge_size == 0);
1122
1123 /* Delete the v2 B-tree */
1124 /* (any v2 B-tree class will work here) */
1125 if(H5B2_delete(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f, NULL, NULL) < 0)
1126 HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree")
1127
1128 /* Reset the information about 'huge' objects in the file */
1129 hdr->huge_bt2_addr = HADDR_UNDEF;
1130 hdr->huge_next_id = 0;
1131 hdr->huge_ids_wrapped = FALSE;
1132
1133 /* Mark heap header as modified */
1134 if(H5HF_hdr_dirty(hdr) < 0)
1135 HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
1136 } /* end if */
1137
1138 done:
1139 FUNC_LEAVE_NOAPI(ret_value)
1140 } /* end H5HF_huge_term() */
1141
1142
1143 /*-------------------------------------------------------------------------
1144 * Function: H5HF_huge_delete
1145 *
1146 * Purpose: Delete all the 'huge' objects in the heap, and the v2 B-tree
1147 * tracker for them
1148 *
1149 * Return: SUCCEED/FAIL
1150 *
1151 * Programmer: Quincey Koziol
1152 * koziol@hdfgroup.org
1153 * Aug 8 2006
1154 *
1155 *-------------------------------------------------------------------------
1156 */
1157 herr_t
H5HF_huge_delete(H5HF_hdr_t * hdr,hid_t dxpl_id)1158 H5HF_huge_delete(H5HF_hdr_t *hdr, hid_t dxpl_id)
1159 {
1160 H5HF_huge_remove_ud_t udata; /* User callback data for v2 B-tree remove call */
1161 H5B2_remove_t op; /* Callback for v2 B-tree removal */
1162 herr_t ret_value = SUCCEED; /* Return value */
1163
1164 FUNC_ENTER_NOAPI_NOINIT
1165
1166 /*
1167 * Check arguments.
1168 */
1169 HDassert(hdr);
1170 HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
1171 HDassert(hdr->huge_nobjs);
1172 HDassert(hdr->huge_size);
1173
1174 /* Set up the callback info */
1175 udata.hdr = hdr;
1176 udata.dxpl_id = dxpl_id;
1177
1178 /* Set the v2 B-tree callback operator */
1179 if(hdr->huge_ids_direct) {
1180 if(hdr->filter_len > 0)
1181 op = H5HF__huge_bt2_filt_dir_remove;
1182 else
1183 op = H5HF__huge_bt2_dir_remove;
1184 } /* end if */
1185 else {
1186 if(hdr->filter_len > 0)
1187 op = H5HF__huge_bt2_filt_indir_remove;
1188 else
1189 op = H5HF__huge_bt2_indir_remove;
1190 } /* end else */
1191
1192 /* Delete the v2 B-tree */
1193 if(H5B2_delete(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f, op, &udata) < 0)
1194 HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree")
1195
1196 done:
1197 FUNC_LEAVE_NOAPI(ret_value)
1198 } /* end H5HF_huge_delete() */
1199
1200