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: H5HFdbg.c
17 * Feb 24 2006
18 * Quincey Koziol <koziol@ncsa.uiuc.edu>
19 *
20 * Purpose: Dump debugging information about a 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 #define H5HF_DEBUGGING /* Need access to fractal heap debugging routines */
31
32 /***********/
33 /* Headers */
34 /***********/
35 #include "H5private.h" /* Generic Functions */
36 #include "H5Eprivate.h" /* Error handling */
37 #include "H5FLprivate.h" /* Free Lists */
38 #include "H5HFpkg.h" /* Fractal heaps */
39 #include "H5MMprivate.h" /* Memory management */
40 #include "H5VMprivate.h" /* Vectors and arrays */
41
42 /****************/
43 /* Local Macros */
44 /****************/
45
46
47 /******************/
48 /* Local Typedefs */
49 /******************/
50
51 /* User data for direct block debugging iterator callback */
52 typedef struct {
53 FILE *stream; /* Stream for output */
54 int indent; /* Indention amount */
55 int fwidth; /* Field width mount */
56 haddr_t dblock_addr; /* Direct block's address */
57 hsize_t dblock_size; /* Direct block's size */
58 uint8_t *marker; /* 'Marker' array for free space */
59 size_t sect_count; /* Number of free space sections in block */
60 size_t amount_free; /* Amount of free space in block */
61 } H5HF_debug_iter_ud1_t;
62
63 /* User data for free space section iterator callback */
64 typedef struct {
65 H5FS_t *fspace; /* Free space manager */
66 FILE *stream; /* Stream for output */
67 int indent; /* Indention amount */
68 int fwidth; /* Field width mount */
69 } H5HF_debug_iter_ud2_t;
70
71
72 /********************/
73 /* Package Typedefs */
74 /********************/
75
76
77 /********************/
78 /* Local Prototypes */
79 /********************/
80
81 static herr_t H5HF_dtable_debug(const H5HF_dtable_t *dtable, FILE *stream,
82 int indent, int fwidth);
83
84
85 /*********************/
86 /* Package Variables */
87 /*********************/
88
89
90 /*****************************/
91 /* Library Private Variables */
92 /*****************************/
93
94
95 /*******************/
96 /* Local Variables */
97 /*******************/
98
99
100 /*-------------------------------------------------------------------------
101 * Function: H5HF_id_print
102 *
103 * Purpose: Prints a fractal heap ID.
104 *
105 * Return: Non-negative on success/Negative on failure
106 *
107 * Programmer: Quincey Koziol
108 * koziol@hdfgroup.org
109 * Aug 20 2015
110 *
111 *-------------------------------------------------------------------------
112 */
113 herr_t
H5HF_id_print(H5HF_t * fh,const void * _id,FILE * stream,int indent,int fwidth)114 H5HF_id_print(H5HF_t *fh, const void *_id, FILE *stream, int indent, int fwidth)
115 {
116 const uint8_t *id = (const uint8_t *)_id; /* Object ID */
117 uint8_t id_flags; /* Heap ID flag bits */
118 hsize_t obj_off; /* Offset of object */
119 size_t obj_len; /* Length of object */
120 char id_type; /* Character for the type of heap ID */
121 herr_t ret_value = SUCCEED; /* Return value */
122
123 FUNC_ENTER_NOAPI_NOINIT
124
125 /*
126 * Check arguments.
127 */
128 HDassert(fh);
129 HDassert(id);
130 HDassert(stream);
131 HDassert(indent >= 0);
132 HDassert(fwidth >= 0);
133
134 /* Get the ID flags */
135 id_flags = *id;
136
137 /* Check for correct heap ID version */
138 if((id_flags & H5HF_ID_VERS_MASK) != H5HF_ID_VERS_CURR)
139 HGOTO_ERROR(H5E_HEAP, H5E_VERSION, FAIL, "incorrect heap ID version")
140
141 /* Check type of object in heap */
142 if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_MAN) {
143 id_type = 'M';
144 } /* end if */
145 else if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_HUGE) {
146 id_type = 'H';
147 } /* end if */
148 else if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_TINY) {
149 id_type = 'T';
150 } /* end if */
151 else {
152 HDfprintf(stderr, "%s: Heap ID type not supported yet!\n", FUNC);
153 HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "heap ID type not supported yet")
154 } /* end else */
155
156 /* Get the length of the heap object */
157 if(H5HF_get_obj_len(fh, id, &obj_len) < 0)
158 HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve heap ID length")
159
160 /* Get the offset of the heap object */
161 if(H5HF_get_obj_off(fh, id, &obj_off) < 0)
162 HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve heap ID length")
163
164 /* Display the heap ID */
165 HDfprintf(stream, "%*s%-*s (%c, %Hu, %Zu)\n", indent, "", fwidth,
166 "Heap ID info: (type, offset, length)",
167 id_type, obj_off, obj_len);
168
169 done:
170 FUNC_LEAVE_NOAPI(ret_value)
171 } /* end H5HF_id_print() */
172
173
174 /*-------------------------------------------------------------------------
175 * Function: H5HF_dtable_debug
176 *
177 * Purpose: Prints debugging info about a doubling table
178 *
179 * Return: Non-negative on success/Negative on failure
180 *
181 * Programmer: Quincey Koziol
182 * koziol@ncsa.uiuc.edu
183 * Feb 28 2006
184 *
185 *-------------------------------------------------------------------------
186 */
187 static herr_t
H5HF_dtable_debug(const H5HF_dtable_t * dtable,FILE * stream,int indent,int fwidth)188 H5HF_dtable_debug(const H5HF_dtable_t *dtable, FILE *stream, int indent, int fwidth)
189 {
190 FUNC_ENTER_NOAPI_NOINIT_NOERR
191
192 /*
193 * Check arguments.
194 */
195 HDassert(dtable);
196 HDassert(stream);
197 HDassert(indent >= 0);
198 HDassert(fwidth >= 0);
199
200 /*
201 * Print the values.
202 */
203 /* Creation parameter values */
204 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
205 "Doubling table width:",
206 dtable->cparam.width);
207 HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
208 "Starting block size:",
209 dtable->cparam.start_block_size);
210 HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
211 "Max. direct block size:",
212 dtable->cparam.max_direct_size);
213 HDfprintf(stream, "%*s%-*s %u (bits)\n", indent, "", fwidth,
214 "Max. index size:",
215 dtable->cparam.max_index);
216 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
217 "Starting # of rows in root indirect block:",
218 dtable->cparam.start_root_rows);
219
220 /* Run-time varying parameter values */
221 HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
222 "Table's root address:",
223 dtable->table_addr);
224 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
225 "Current # of rows in root indirect block:",
226 dtable->curr_root_rows);
227
228 /* Computed values */
229 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
230 "Max. # of rows in root indirect block:",
231 dtable->max_root_rows);
232 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
233 "Max. # of direct rows in any indirect block:",
234 dtable->max_direct_rows);
235 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
236 "# of bits for IDs in first row:",
237 dtable->first_row_bits);
238 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
239 "# of IDs in first row:",
240 dtable->num_id_first_row);
241
242 FUNC_LEAVE_NOAPI(SUCCEED)
243 } /* end H5HF_dtable_debug() */
244
245
246 /*-------------------------------------------------------------------------
247 * Function: H5HF_hdr_print
248 *
249 * Purpose: Prints info about a fractal heap header.
250 *
251 * Return: Non-negative on success/Negative on failure
252 *
253 * Programmer: Quincey Koziol
254 * koziol@hdfgroup.org
255 * Feb 23 2012
256 *
257 *-------------------------------------------------------------------------
258 */
259 void
H5HF_hdr_print(const H5HF_hdr_t * hdr,hbool_t dump_internal,FILE * stream,int indent,int fwidth)260 H5HF_hdr_print(const H5HF_hdr_t *hdr, hbool_t dump_internal, FILE *stream, int indent, int fwidth)
261 {
262 FUNC_ENTER_NOAPI_NOINIT_NOERR
263
264 /*
265 * Check arguments.
266 */
267 HDassert(hdr);
268 HDassert(stream);
269 HDassert(indent >= 0);
270 HDassert(fwidth >= 0);
271
272 /* Print opening message */
273 HDfprintf(stream, "%*sFractal Heap Header...\n", indent, "");
274
275 /*
276 * Print the values.
277 */
278 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
279 "Heap is:",
280 hdr->man_dtable.curr_root_rows > 0 ? "Indirect" : "Direct");
281 HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth,
282 "Objects stored in 'debugging' format:",
283 hdr->debug_objs);
284 HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth,
285 "'Write once' flag:",
286 hdr->write_once);
287 HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth,
288 "'Huge' object IDs have wrapped:",
289 hdr->huge_ids_wrapped);
290 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
291 "Free space in managed blocks:",
292 hdr->total_man_free);
293 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
294 "Managed space data block size:",
295 hdr->man_size);
296 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
297 "Total managed space allocated:",
298 hdr->man_alloc_size);
299 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
300 "Offset of managed space iterator:",
301 hdr->man_iter_off);
302 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
303 "Number of managed objects in heap:",
304 hdr->man_nobjs);
305 HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
306 "Address of free space manager for managed blocks:",
307 hdr->fs_addr);
308 HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
309 "Max. size of managed object:",
310 (unsigned long)hdr->max_man_size);
311 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
312 "'Huge' object space used:",
313 hdr->huge_size);
314 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
315 "Number of 'huge' objects in heap:",
316 hdr->huge_nobjs);
317 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
318 "ID of next 'huge' object:",
319 hdr->huge_next_id);
320 HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
321 "Address of v2 B-tree for 'huge' objects:",
322 hdr->huge_bt2_addr);
323 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
324 "'Tiny' object space used:",
325 hdr->tiny_size);
326 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
327 "Number of 'tiny' objects in heap:",
328 hdr->tiny_nobjs);
329
330 HDfprintf(stream, "%*sManaged Objects Doubling-Table Info...\n", indent, "");
331 H5HF_dtable_debug(&hdr->man_dtable, stream, indent + 3, MAX(0, fwidth - 3));
332
333 /* Print information about I/O filters */
334 if(hdr->filter_len > 0) {
335 HDfprintf(stream, "%*sI/O filter Info...\n", indent, "");
336 if(hdr->man_dtable.curr_root_rows == 0) {
337 HDfprintf(stream, "%*s%-*s %Zu\n", indent + 3, "", MAX(0, fwidth - 3),
338 "Compressed size of root direct block:",
339 hdr->pline_root_direct_size);
340 HDfprintf(stream, "%*s%-*s %x\n", indent + 3, "", MAX(0, fwidth - 3),
341 "Filter mask for root direct block:",
342 hdr->pline_root_direct_filter_mask);
343 } /* end if */
344 H5O_debug_id(H5O_PLINE_ID, hdr->f, &(hdr->pline), stream, indent + 3, MAX(0, fwidth - 3));
345 } /* end if */
346
347 /* Print internal (runtime) information, if requested */
348 if(dump_internal) {
349 HDfprintf(stream, "%*sFractal Heap Header Internal Information:\n", indent, "");
350
351 /* Dump root iblock, if there is one */
352 HDfprintf(stream, "%*s%-*s %x\n", indent + 3, "", MAX(0, fwidth - 3),
353 "Root indirect block flags:",
354 hdr->root_iblock_flags);
355 HDfprintf(stream, "%*s%-*s %p\n", indent + 3, "", MAX(0, fwidth - 3),
356 "Root indirect block pointer:",
357 hdr->root_iblock);
358 if(hdr->root_iblock)
359 H5HF_iblock_print(hdr->root_iblock, dump_internal, stream, indent + 3, fwidth);
360 } /* end if */
361
362 FUNC_LEAVE_NOAPI_VOID
363 } /* end H5HF_hdr_print() */
364
365
366 /*-------------------------------------------------------------------------
367 * Function: H5HF_hdr_debug
368 *
369 * Purpose: Prints debugging info about a fractal heap header.
370 *
371 * Return: Non-negative on success/Negative on failure
372 *
373 * Programmer: Quincey Koziol
374 * koziol@ncsa.uiuc.edu
375 * Feb 24 2006
376 *
377 *-------------------------------------------------------------------------
378 */
379 herr_t
H5HF_hdr_debug(H5F_t * f,haddr_t addr,FILE * stream,int indent,int fwidth)380 H5HF_hdr_debug(H5F_t *f, haddr_t addr, FILE *stream, int indent, int fwidth)
381 {
382 H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
383 herr_t ret_value = SUCCEED; /* Return value */
384
385 FUNC_ENTER_NOAPI(FAIL)
386
387 /*
388 * Check arguments.
389 */
390 HDassert(f);
391 HDassert(H5F_addr_defined(addr));
392 HDassert(stream);
393 HDassert(indent >= 0);
394 HDassert(fwidth >= 0);
395
396 /* Load the fractal heap header */
397 if(NULL == (hdr = H5HF__hdr_protect(f, addr, H5AC__READ_ONLY_FLAG)))
398 HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
399
400 /* Print the information about the heap's header */
401 H5HF_hdr_print(hdr, FALSE, stream, indent, fwidth);
402
403 done:
404 if(hdr && H5AC_unprotect(f, H5AC_FHEAP_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
405 HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header")
406
407 FUNC_LEAVE_NOAPI(ret_value)
408 } /* end H5HF_hdr_debug() */
409
410
411 /*-------------------------------------------------------------------------
412 * Function: H5HF_dblock_debug_cb
413 *
414 * Purpose: Detect free space within a direct block
415 *
416 * Return: Non-negative on success/Negative on failure
417 *
418 * Programmer: Quincey Koziol
419 * koziol@ncsa.uiuc.edu
420 * May 13 2006
421 *
422 *-------------------------------------------------------------------------
423 */
424 static herr_t
H5HF_dblock_debug_cb(H5FS_section_info_t * _sect,void * _udata)425 H5HF_dblock_debug_cb(H5FS_section_info_t *_sect, void *_udata)
426 {
427 H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Section to dump info */
428 H5HF_debug_iter_ud1_t *udata = (H5HF_debug_iter_ud1_t *)_udata; /* User data for callbacks */
429 haddr_t sect_start, sect_end; /* Section's beginning and ending offsets */
430 haddr_t dblock_start, dblock_end; /* Direct block's beginning and ending offsets */
431
432 FUNC_ENTER_NOAPI_NOINIT_NOERR
433
434 /*
435 * Check arguments.
436 */
437 HDassert(sect);
438 HDassert(udata);
439
440 /* Set up some local variables, for convenience */
441 sect_start = sect->sect_info.addr;
442 sect_end = (sect->sect_info.addr + sect->sect_info.size) - 1;
443 HDassert(sect_end >= sect_start);
444 dblock_start = udata->dblock_addr;
445 dblock_end = (udata->dblock_addr + udata->dblock_size) - 1;
446 HDassert(dblock_end >= dblock_start);
447
448 /* Check for overlap between free space section & direct block */
449 if((sect_start <= dblock_end && sect_end >=dblock_start) || /* section within or overlaps w/beginning of direct block*/
450 (sect_start <= dblock_end && sect_end >=dblock_end)) { /* section overlaps w/end of direct block */
451 char temp_str[32]; /* Temporary string for formatting */
452 size_t start, end; /* Start & end of the overlapping area */
453 size_t len; /* Length of the overlapping area */
454 size_t overlap; /* Track any overlaps */
455 size_t u; /* Local index variable */
456
457 /* Calculate the starting & ending */
458 if(sect_start < dblock_start)
459 start = 0;
460 else
461 H5_CHECKED_ASSIGN(start, size_t, (sect_start - dblock_start), hsize_t)
462 if(sect_end > dblock_end)
463 H5_CHECKED_ASSIGN(end, size_t, udata->dblock_size, hsize_t)
464 else
465 H5_CHECKED_ASSIGN(end, size_t, ((sect_end - dblock_start) + 1), hsize_t)
466
467 /* Calculate the length */
468 len = end - start;
469
470 HDsnprintf(temp_str, sizeof(temp_str), "Section #%u:", (unsigned)udata->sect_count);
471 HDfprintf(udata->stream, "%*s%-*s %8Zu, %8Zu\n", udata->indent + 3, "", MAX(0, udata->fwidth - 9),
472 temp_str,
473 start, len);
474 udata->sect_count++;
475
476 /* Mark this node's free space & check for overlaps w/other sections */
477 overlap = 0;
478 for(u = start; u < end; u++) {
479 if(udata->marker[u])
480 overlap++;
481 udata->marker[u] = 1;
482 } /* end for */
483
484 /* Flag overlaps */
485 if (overlap)
486 fprintf(udata->stream, "***THAT FREE BLOCK OVERLAPPED A PREVIOUS ONE!\n");
487 else
488 udata->amount_free += len;
489 } /* end if */
490
491 FUNC_LEAVE_NOAPI(SUCCEED)
492 } /* end H5HF_dblock_debug_cb() */
493
494
495 /*-------------------------------------------------------------------------
496 * Function: H5HF_dblock_debug
497 *
498 * Purpose: Prints debugging info about a fractal heap direct block.
499 *
500 * Return: Non-negative on success/Negative on failure
501 *
502 * Programmer: Quincey Koziol
503 * koziol@ncsa.uiuc.edu
504 * Feb 28 2006
505 *
506 *-------------------------------------------------------------------------
507 */
508 herr_t
H5HF_dblock_debug(H5F_t * f,haddr_t addr,FILE * stream,int indent,int fwidth,haddr_t hdr_addr,size_t block_size)509 H5HF_dblock_debug(H5F_t *f, haddr_t addr, FILE *stream, int indent, int fwidth,
510 haddr_t hdr_addr, size_t block_size)
511 {
512 H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
513 H5HF_direct_t *dblock = NULL; /* Fractal heap direct block info */
514 size_t blk_prefix_size; /* Size of prefix for block */
515 size_t amount_free; /* Amount of free space in block */
516 uint8_t *marker = NULL; /* Track free space for block */
517 herr_t ret_value = SUCCEED; /* Return value */
518
519 FUNC_ENTER_NOAPI(FAIL)
520
521 /*
522 * Check arguments.
523 */
524 HDassert(f);
525 HDassert(H5F_addr_defined(addr));
526 HDassert(stream);
527 HDassert(indent >= 0);
528 HDassert(fwidth >= 0);
529 HDassert(H5F_addr_defined(hdr_addr));
530 HDassert(block_size > 0);
531
532 /* Load the fractal heap header */
533 if(NULL == (hdr = H5HF__hdr_protect(f, hdr_addr, H5AC__READ_ONLY_FLAG)))
534 HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
535
536 /*
537 * Load the heap direct block
538 */
539 if(NULL == (dblock = H5HF__man_dblock_protect(hdr, addr, block_size, NULL, 0, H5AC__READ_ONLY_FLAG)))
540 HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap direct block")
541
542 /* Print opening message */
543 HDfprintf(stream, "%*sFractal Heap Direct Block...\n", indent, "");
544
545 /*
546 * Print the values.
547 */
548 HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
549 "Address of fractal heap that owns this block:",
550 hdr->heap_addr);
551 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
552 "Offset of direct block in heap:",
553 dblock->block_off);
554 blk_prefix_size = H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr);
555 HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
556 "Size of block header:",
557 blk_prefix_size);
558
559 /* Allocate space for the free space markers */
560 if(NULL == (marker = (uint8_t *)H5MM_calloc(dblock->size)))
561 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
562
563 /* Initialize the free space information for the heap */
564 if(H5HF__space_start(hdr, FALSE) < 0)
565 HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
566
567 /* If there is a free space manager for the heap, check for sections that overlap this block */
568 if(hdr->fspace) {
569 H5HF_debug_iter_ud1_t udata; /* User data for callbacks */
570
571 /* Prepare user data for section iteration callback */
572 udata.stream = stream;
573 udata.indent = indent;
574 udata.fwidth = fwidth;
575 udata.dblock_addr = dblock->block_off;
576 udata.dblock_size = block_size;
577 udata.marker = marker;
578 udata.sect_count = 0;
579 udata.amount_free = 0;
580
581 /* Print header */
582 HDfprintf(stream, "%*sFree Blocks (offset, size):\n", indent, "");
583
584 /* Iterate over the free space sections, to detect overlaps with this block */
585 if(H5FS_sect_iterate(f, hdr->fspace, H5HF_dblock_debug_cb, &udata) < 0)
586 HGOTO_ERROR(H5E_HEAP, H5E_BADITER, FAIL, "can't iterate over heap's free space")
587
588 /* Close the free space information */
589 if(H5HF__space_close(hdr) < 0)
590 HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release free space info")
591
592 /* Keep the amount of space free */
593 amount_free = udata.amount_free;
594
595 /* Check for no free space */
596 if(amount_free == 0)
597 HDfprintf(stream, "%*s<none>\n", indent + 3, "");
598 } /* end if */
599 else
600 amount_free = 0;
601
602 HDfprintf(stream, "%*s%-*s %.2f%%\n", indent, "", fwidth,
603 "Percent of available space for data used:",
604 ((double)100.0f * (double)((dblock->size - blk_prefix_size) - amount_free) / (double)(dblock->size - blk_prefix_size)));
605
606 /*
607 * Print the data in a VMS-style octal dump.
608 */
609 H5_buffer_dump(stream, indent, dblock->blk, marker, (size_t)0, dblock->size);
610
611 done:
612 if(dblock && H5AC_unprotect(f, H5AC_FHEAP_DBLOCK, addr, dblock, H5AC__NO_FLAGS_SET) < 0)
613 HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap direct block")
614 if(hdr && H5AC_unprotect(f, H5AC_FHEAP_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
615 HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header")
616 H5MM_xfree(marker);
617
618 FUNC_LEAVE_NOAPI(ret_value)
619 } /* end H5HF_dblock_debug() */
620
621
622 /*-------------------------------------------------------------------------
623 * Function: H5HF_iblock_print
624 *
625 * Purpose: Prints debugging info about a fractal heap indirect block.
626 *
627 * Return: Non-negative on success/Negative on failure
628 *
629 * Programmer: Quincey Koziol
630 * koziol@hdfgroup.org
631 * Feb 23 2012
632 *
633 *-------------------------------------------------------------------------
634 */
635 void
H5HF_iblock_print(const H5HF_indirect_t * iblock,hbool_t dump_internal,FILE * stream,int indent,int fwidth)636 H5HF_iblock_print(const H5HF_indirect_t *iblock,
637 hbool_t dump_internal, FILE *stream, int indent, int fwidth)
638 {
639 const H5HF_hdr_t *hdr; /* Pointer to heap's header */
640 char temp_str[64]; /* Temporary string, for formatting */
641 size_t u, v; /* Local index variable */
642
643 FUNC_ENTER_NOAPI_NOINIT_NOERR
644
645 /*
646 * Check arguments.
647 */
648 HDassert(iblock);
649 HDassert(iblock->hdr);
650 HDassert(stream);
651 HDassert(indent >= 0);
652 HDassert(fwidth >= 0);
653
654 /* Set up convenience variables */
655 hdr = iblock->hdr;
656
657 /* Print opening message */
658 HDfprintf(stream, "%*sFractal Heap Indirect Block...\n", indent, "");
659
660 /*
661 * Print the values.
662 */
663 HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
664 "Address of fractal heap that owns this block:",
665 hdr->heap_addr);
666 HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
667 "Offset of indirect block in heap:",
668 iblock->block_off);
669 HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
670 "Size of indirect block:",
671 iblock->size);
672 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
673 "Current # of rows:",
674 iblock->nrows);
675 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
676 "Max. # of rows:",
677 iblock->max_rows);
678 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
679 "Max direct block rows:",
680 hdr->man_dtable.max_direct_rows);
681
682 /* Print the entry tables */
683 if(hdr->filter_len > 0)
684 HDfprintf(stream, "%*sDirect Block Entries: (address/compressed size/filter mask)\n", indent, "");
685 else
686 HDfprintf(stream, "%*sDirect Block Entries: (address)\n", indent, "");
687 for(u = 0; u < hdr->man_dtable.max_direct_rows && u < iblock->nrows; u++) {
688 HDsnprintf(temp_str, sizeof(temp_str), "Row #%u: (block size: %lu)", (unsigned)u, (unsigned long)hdr->man_dtable.row_block_size[u]);
689 HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
690 temp_str);
691 for(v = 0; v < hdr->man_dtable.cparam.width; v++) {
692 size_t off = (u * hdr->man_dtable.cparam.width) + v;
693
694 HDsnprintf(temp_str, sizeof(temp_str), "Col #%u:", (unsigned)v);
695 if(hdr->filter_len > 0)
696 HDfprintf(stream, "%*s%-*s %9a/%6Zu/%x\n", indent + 6, "", MAX(0, fwidth - 6),
697 temp_str,
698 iblock->ents[off].addr,
699 iblock->filt_ents[off].size,
700 iblock->filt_ents[off].filter_mask);
701 else
702 HDfprintf(stream, "%*s%-*s %9a\n", indent + 6, "", MAX(0, fwidth - 6),
703 temp_str,
704 iblock->ents[off].addr);
705 } /* end for */
706 } /* end for */
707 HDfprintf(stream, "%*sIndirect Block Entries:\n", indent, "");
708 if(iblock->nrows > hdr->man_dtable.max_direct_rows) {
709 unsigned first_row_bits; /* Number of bits used bit addresses in first row */
710 unsigned num_indirect_rows; /* Number of rows of blocks in each indirect block */
711
712 first_row_bits = H5VM_log2_of2((uint32_t)hdr->man_dtable.cparam.start_block_size) +
713 H5VM_log2_of2(hdr->man_dtable.cparam.width);
714 for(u = hdr->man_dtable.max_direct_rows; u < iblock->nrows; u++) {
715 num_indirect_rows = (H5VM_log2_gen(hdr->man_dtable.row_block_size[u]) - first_row_bits) + 1;
716 HDsnprintf(temp_str, sizeof(temp_str), "Row #%u: (# of rows: %u)", (unsigned)u, num_indirect_rows);
717 HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
718 temp_str);
719 for(v = 0; v < hdr->man_dtable.cparam.width; v++) {
720 size_t off = (u * hdr->man_dtable.cparam.width) + v;
721
722 HDsnprintf(temp_str, sizeof(temp_str), "Col #%u:", (unsigned)v);
723 HDfprintf(stream, "%*s%-*s %9a\n", indent + 6, "", MAX(0, fwidth - 6),
724 temp_str,
725 iblock->ents[off].addr);
726 } /* end for */
727 } /* end for */
728 } /* end if */
729 else
730 HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
731 "<none>");
732
733 /* Print internal (runtime) information, if requested */
734 if(dump_internal) {
735 HDfprintf(stream, "%*sFractal Indirect Block Internal Information:\n", indent, "");
736
737 /* Print general information */
738 HDfprintf(stream, "%*s%-*s %Zu\n", indent + 3, "", MAX(0, fwidth - 3),
739 "Reference count:",
740 iblock->rc);
741
742 /* Print parent's information */
743 HDfprintf(stream, "%*s%-*s %p\n", indent + 3, "", MAX(0, fwidth - 3),
744 "Parent indirect block address:",
745 iblock->parent);
746 if(iblock->parent)
747 H5HF_iblock_print(iblock->parent, TRUE, stream, indent + 6, fwidth);
748 } /* end if */
749
750 FUNC_LEAVE_NOAPI_VOID
751 } /* end H5HF_iblock_print() */
752
753
754 /*-------------------------------------------------------------------------
755 * Function: H5HF_iblock_debug
756 *
757 * Purpose: Prints debugging info about a fractal heap indirect block.
758 *
759 * Return: Non-negative on success/Negative on failure
760 *
761 * Programmer: Quincey Koziol
762 * koziol@ncsa.uiuc.edu
763 * Mar 7 2006
764 *
765 *-------------------------------------------------------------------------
766 */
767 herr_t
H5HF_iblock_debug(H5F_t * f,haddr_t addr,FILE * stream,int indent,int fwidth,haddr_t hdr_addr,unsigned nrows)768 H5HF_iblock_debug(H5F_t *f, haddr_t addr, FILE *stream, int indent, int fwidth,
769 haddr_t hdr_addr, unsigned nrows)
770 {
771 H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
772 H5HF_indirect_t *iblock = NULL; /* Fractal heap direct block info */
773 hbool_t did_protect; /* Whether we protected the indirect block or not */
774 herr_t ret_value = SUCCEED; /* Return value */
775
776 FUNC_ENTER_NOAPI(FAIL)
777
778 /*
779 * Check arguments.
780 */
781 HDassert(f);
782 HDassert(H5F_addr_defined(addr));
783 HDassert(stream);
784 HDassert(indent >= 0);
785 HDassert(fwidth >= 0);
786 HDassert(H5F_addr_defined(hdr_addr));
787 HDassert(nrows > 0);
788
789 /* Load the fractal heap header */
790 if(NULL == (hdr = H5HF__hdr_protect(f, hdr_addr, H5AC__READ_ONLY_FLAG)))
791 HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
792
793 /*
794 * Load the heap indirect block
795 */
796 if(NULL == (iblock = H5HF__man_iblock_protect(hdr, addr, nrows, NULL, 0, FALSE, H5AC__READ_ONLY_FLAG, &did_protect)))
797 HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap indirect block")
798
799 /* Print the information about the heap's indirect block */
800 H5HF_iblock_print(iblock, FALSE, stream, indent, fwidth);
801
802 done:
803 if(iblock && H5HF__man_iblock_unprotect(iblock, H5AC__NO_FLAGS_SET, did_protect) < 0)
804 HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap direct block")
805 if(hdr && H5AC_unprotect(f, H5AC_FHEAP_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
806 HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header")
807
808 FUNC_LEAVE_NOAPI(ret_value)
809 } /* end H5HF_iblock_debug() */
810
811
812 /*-------------------------------------------------------------------------
813 * Function: H5HF_sects_debug_cb
814 *
815 * Purpose: Prints debugging info about a free space section for a fractal heap.
816 *
817 * Return: Non-negative on success/Negative on failure
818 *
819 * Programmer: Quincey Koziol
820 * koziol@ncsa.uiuc.edu
821 * May 13 2006
822 *
823 *-------------------------------------------------------------------------
824 */
825 static herr_t
H5HF_sects_debug_cb(H5FS_section_info_t * _sect,void * _udata)826 H5HF_sects_debug_cb(H5FS_section_info_t *_sect, void *_udata)
827 {
828 H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Section to dump info */
829 H5HF_debug_iter_ud2_t *udata = (H5HF_debug_iter_ud2_t *)_udata; /* User data for callbacks */
830 herr_t ret_value = SUCCEED; /* Return value */
831
832 FUNC_ENTER_NOAPI_NOINIT
833
834 /*
835 * Check arguments.
836 */
837 HDassert(sect);
838 HDassert(udata);
839
840 /* Print generic section information */
841 HDfprintf(udata->stream, "%*s%-*s %s\n", udata->indent, "", udata->fwidth,
842 "Section type:",
843 (sect->sect_info.type == H5HF_FSPACE_SECT_SINGLE ? "single" :
844 (sect->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW ? "first row" :
845 (sect->sect_info.type == H5HF_FSPACE_SECT_NORMAL_ROW ? "normal row" : "unknown"))));
846 HDfprintf(udata->stream, "%*s%-*s %a\n", udata->indent, "", udata->fwidth,
847 "Section address:",
848 sect->sect_info.addr);
849 HDfprintf(udata->stream, "%*s%-*s %Hu\n", udata->indent, "", udata->fwidth,
850 "Section size:",
851 sect->sect_info.size);
852 #ifdef QAK
853 HDfprintf(udata->stream, "%*s%-*s %s\n", udata->indent, "", udata->fwidth,
854 "Section state:",
855 (sect->sect_info.state == H5FS_SECT_LIVE ? "live" : "serialized"));
856 #endif /* QAK */
857
858 /* Dump section-specific debugging information */
859 if(H5FS_sect_debug(udata->fspace, _sect, udata->stream, udata->indent + 3, MAX(0, udata->fwidth - 3)) < 0)
860 HGOTO_ERROR(H5E_HEAP, H5E_BADITER, FAIL, "can't dump section's debugging info")
861
862 done:
863 FUNC_LEAVE_NOAPI(ret_value)
864 } /* end H5HF_sects_debug_cb() */
865
866
867 /*-------------------------------------------------------------------------
868 * Function: H5HF_sects_debug
869 *
870 * Purpose: Prints debugging info about free space sections for a fractal heap.
871 *
872 * Return: Non-negative on success/Negative on failure
873 *
874 * Programmer: Quincey Koziol
875 * koziol@ncsa.uiuc.edu
876 * May 9 2006
877 *
878 *-------------------------------------------------------------------------
879 */
880 herr_t
H5HF_sects_debug(H5F_t * f,haddr_t fh_addr,FILE * stream,int indent,int fwidth)881 H5HF_sects_debug(H5F_t *f, haddr_t fh_addr, FILE *stream, int indent,
882 int fwidth)
883 {
884 H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
885 herr_t ret_value = SUCCEED; /* Return value */
886
887 FUNC_ENTER_NOAPI(FAIL)
888
889 /*
890 * Check arguments.
891 */
892 HDassert(f);
893 HDassert(H5F_addr_defined(fh_addr));
894 HDassert(stream);
895 HDassert(indent >= 0);
896 HDassert(fwidth >= 0);
897
898 /* Load the fractal heap header */
899 if(NULL == (hdr = H5HF__hdr_protect(f, fh_addr, H5AC__READ_ONLY_FLAG)))
900 HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
901
902 /* Initialize the free space information for the heap */
903 if(H5HF__space_start(hdr, FALSE) < 0)
904 HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
905
906 /* If there is a free space manager for the heap, iterate over them */
907 if(hdr->fspace) {
908 H5HF_debug_iter_ud2_t udata; /* User data for callbacks */
909
910 /* Prepare user data for section iteration callback */
911 udata.fspace = hdr->fspace;
912 udata.stream = stream;
913 udata.indent = indent;
914 udata.fwidth = fwidth;
915
916 /* Iterate over all the free space sections */
917 if(H5FS_sect_iterate(f, hdr->fspace, H5HF_sects_debug_cb, &udata) < 0)
918 HGOTO_ERROR(H5E_HEAP, H5E_BADITER, FAIL, "can't iterate over heap's free space")
919
920 /* Close the free space information */
921 if(H5HF__space_close(hdr) < 0)
922 HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release free space info")
923 } /* end if */
924
925 done:
926 if(hdr && H5AC_unprotect(f, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
927 HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header")
928
929 FUNC_LEAVE_NOAPI(ret_value)
930 } /* end H5HF_sects_debug() */
931
932