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://www.hdfgroup.org/licenses. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /* Programmer: Vailin Choi
15 * Thursday, April 30, 2009
16 *
17 * Purpose: Fixed array indexed (chunked) I/O functions.
18 * The chunk coordinate is mapped as an index into an array of
19 * disk addresses for the chunks.
20 *
21 */
22
23 /****************/
24 /* Module Setup */
25 /****************/
26
27 #include "H5Dmodule.h" /* This source code file is part of the H5D module */
28
29 /***********/
30 /* Headers */
31 /***********/
32 #include "H5private.h" /* Generic Functions */
33 #include "H5Dpkg.h" /* Datasets */
34 #include "H5Eprivate.h" /* Error handling */
35 #include "H5FAprivate.h" /* Fixed arrays */
36 #include "H5FLprivate.h" /* Free Lists */
37 #include "H5MFprivate.h" /* File space management */
38 #include "H5VMprivate.h" /* Vector functions */
39
40 /****************/
41 /* Local Macros */
42 /****************/
43
44 /* Value to fill unset array elements with */
45 #define H5D_FARRAY_FILL HADDR_UNDEF
46 #define H5D_FARRAY_FILT_FILL \
47 { \
48 HADDR_UNDEF, 0, 0 \
49 }
50
51 /******************/
52 /* Local Typedefs */
53 /******************/
54
55 /* Fixed array create/open user data */
56 typedef struct H5D_farray_ctx_ud_t {
57 const H5F_t *f; /* Pointer to file info */
58 uint32_t chunk_size; /* Size of chunk (bytes) */
59 } H5D_farray_ctx_ud_t;
60
61 /* Fixed array callback context */
62 typedef struct H5D_farray_ctx_t {
63 size_t file_addr_len; /* Size of addresses in the file (bytes) */
64 size_t chunk_size_len; /* Size of chunk sizes in the file (bytes) */
65 } H5D_farray_ctx_t;
66
67 /* Fixed Array callback info for iteration over chunks */
68 typedef struct H5D_farray_it_ud_t {
69 H5D_chunk_common_ud_t common; /* Common info for Fixed Array user data (must be first) */
70 H5D_chunk_rec_t chunk_rec; /* Generic chunk record for callback */
71 hbool_t filtered; /* Whether the chunks are filtered */
72 H5D_chunk_cb_func_t cb; /* Chunk callback routine */
73 void * udata; /* User data for chunk callback routine */
74 } H5D_farray_it_ud_t;
75
76 /* Native fixed array element for chunks w/filters */
77 typedef struct H5D_farray_filt_elmt_t {
78 haddr_t addr; /* Address of chunk */
79 uint32_t nbytes; /* Size of chunk (in file) */
80 uint32_t filter_mask; /* Excluded filters for chunk */
81 } H5D_farray_filt_elmt_t;
82
83 /********************/
84 /* Local Prototypes */
85 /********************/
86
87 /* Fixed Array iterator callbacks */
88 static int H5D__farray_idx_iterate_cb(hsize_t idx, const void *_elmt, void *_udata);
89 static int H5D__farray_idx_delete_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata);
90
91 /* Fixed array class callbacks for chunks w/o filters */
92 static void * H5D__farray_crt_context(void *udata);
93 static herr_t H5D__farray_dst_context(void *ctx);
94 static herr_t H5D__farray_fill(void *nat_blk, size_t nelmts);
95 static herr_t H5D__farray_encode(void *raw, const void *elmt, size_t nelmts, void *ctx);
96 static herr_t H5D__farray_decode(const void *raw, void *elmt, size_t nelmts, void *ctx);
97 static herr_t H5D__farray_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const void *elmt);
98 static void * H5D__farray_crt_dbg_context(H5F_t *f, haddr_t obj_addr);
99 static herr_t H5D__farray_dst_dbg_context(void *dbg_ctx);
100
101 /* Fixed array class callbacks for chunks w/filters */
102 /* (some shared with callbacks for chunks w/o filters) */
103 static herr_t H5D__farray_filt_fill(void *nat_blk, size_t nelmts);
104 static herr_t H5D__farray_filt_encode(void *raw, const void *elmt, size_t nelmts, void *ctx);
105 static herr_t H5D__farray_filt_decode(const void *raw, void *elmt, size_t nelmts, void *ctx);
106 static herr_t H5D__farray_filt_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const void *elmt);
107
108 /* Chunked layout indexing callbacks */
109 static herr_t H5D__farray_idx_init(const H5D_chk_idx_info_t *idx_info, const H5S_t *space,
110 haddr_t dset_ohdr_addr);
111 static herr_t H5D__farray_idx_create(const H5D_chk_idx_info_t *idx_info);
112 static hbool_t H5D__farray_idx_is_space_alloc(const H5O_storage_chunk_t *storage);
113 static herr_t H5D__farray_idx_insert(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata,
114 const H5D_t *dset);
115 static herr_t H5D__farray_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata);
116 static int H5D__farray_idx_iterate(const H5D_chk_idx_info_t *idx_info, H5D_chunk_cb_func_t chunk_cb,
117 void *chunk_udata);
118 static herr_t H5D__farray_idx_remove(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata);
119 static herr_t H5D__farray_idx_delete(const H5D_chk_idx_info_t *idx_info);
120 static herr_t H5D__farray_idx_copy_setup(const H5D_chk_idx_info_t *idx_info_src,
121 const H5D_chk_idx_info_t *idx_info_dst);
122 static herr_t H5D__farray_idx_copy_shutdown(H5O_storage_chunk_t *storage_src,
123 H5O_storage_chunk_t *storage_dst);
124 static herr_t H5D__farray_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *size);
125 static herr_t H5D__farray_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr);
126 static herr_t H5D__farray_idx_dump(const H5O_storage_chunk_t *storage, FILE *stream);
127 static herr_t H5D__farray_idx_dest(const H5D_chk_idx_info_t *idx_info);
128
129 /* Generic fixed array routines */
130 static herr_t H5D__farray_idx_open(const H5D_chk_idx_info_t *idx_info);
131 static herr_t H5D__farray_idx_depend(const H5D_chk_idx_info_t *idx_info);
132
133 /*********************/
134 /* Package Variables */
135 /*********************/
136
137 /* Fixed array indexed chunk I/O ops */
138 const H5D_chunk_ops_t H5D_COPS_FARRAY[1] = {{
139 TRUE, /* Fixed array indices support SWMR access */
140 H5D__farray_idx_init, /* init */
141 H5D__farray_idx_create, /* create */
142 H5D__farray_idx_is_space_alloc, /* is_space_alloc */
143 H5D__farray_idx_insert, /* insert */
144 H5D__farray_idx_get_addr, /* get_addr */
145 NULL, /* resize */
146 H5D__farray_idx_iterate, /* iterate */
147 H5D__farray_idx_remove, /* remove */
148 H5D__farray_idx_delete, /* delete */
149 H5D__farray_idx_copy_setup, /* copy_setup */
150 H5D__farray_idx_copy_shutdown, /* copy_shutdown */
151 H5D__farray_idx_size, /* size */
152 H5D__farray_idx_reset, /* reset */
153 H5D__farray_idx_dump, /* dump */
154 H5D__farray_idx_dest /* destroy */
155 }};
156
157 /*****************************/
158 /* Library Private Variables */
159 /*****************************/
160
161 /*******************/
162 /* Local Variables */
163 /*******************/
164
165 /* Fixed array class callbacks for dataset chunks w/o filters */
166 const H5FA_class_t H5FA_CLS_CHUNK[1] = {{
167 H5FA_CLS_CHUNK_ID, /* Type of fixed array */
168 "Chunk w/o filters", /* Name of fixed array class */
169 sizeof(haddr_t), /* Size of native element */
170 H5D__farray_crt_context, /* Create context */
171 H5D__farray_dst_context, /* Destroy context */
172 H5D__farray_fill, /* Fill block of missing elements callback */
173 H5D__farray_encode, /* Element encoding callback */
174 H5D__farray_decode, /* Element decoding callback */
175 H5D__farray_debug, /* Element debugging callback */
176 H5D__farray_crt_dbg_context, /* Create debugging context */
177 H5D__farray_dst_dbg_context /* Destroy debugging context */
178 }};
179
180 /* Fixed array class callbacks for dataset chunks w/filters */
181 const H5FA_class_t H5FA_CLS_FILT_CHUNK[1] = {{
182 H5FA_CLS_FILT_CHUNK_ID, /* Type of fixed array */
183 "Chunk w/filters", /* Name of fixed array class */
184 sizeof(H5D_farray_filt_elmt_t), /* Size of native element */
185 H5D__farray_crt_context, /* Create context */
186 H5D__farray_dst_context, /* Destroy context */
187 H5D__farray_filt_fill, /* Fill block of missing elements callback */
188 H5D__farray_filt_encode, /* Element encoding callback */
189 H5D__farray_filt_decode, /* Element decoding callback */
190 H5D__farray_filt_debug, /* Element debugging callback */
191 H5D__farray_crt_dbg_context, /* Create debugging context */
192 H5D__farray_dst_dbg_context /* Destroy debugging context */
193 }};
194
195 /* Declare a free list to manage the H5D_farray_ctx_t struct */
196 H5FL_DEFINE_STATIC(H5D_farray_ctx_t);
197
198 /* Declare a free list to manage the H5D_farray_ctx_ud_t struct */
199 H5FL_DEFINE_STATIC(H5D_farray_ctx_ud_t);
200
201 /*-------------------------------------------------------------------------
202 * Function: H5D__farray_crt_context
203 *
204 * Purpose: Create context for callbacks
205 *
206 * Return: Success: non-NULL
207 * Failure: NULL
208 *
209 * Programmer: Vailin Choi
210 * Thursday, April 30, 2009
211 *
212 *-------------------------------------------------------------------------
213 */
214 static void *
H5D__farray_crt_context(void * _udata)215 H5D__farray_crt_context(void *_udata)
216 {
217 H5D_farray_ctx_t * ctx; /* Fixed array callback context */
218 H5D_farray_ctx_ud_t *udata = (H5D_farray_ctx_ud_t *)_udata; /* User data for fixed array context */
219 void * ret_value = NULL; /* Return value */
220
221 FUNC_ENTER_STATIC
222
223 /* Sanity checks */
224 HDassert(udata);
225 HDassert(udata->f);
226 HDassert(udata->chunk_size > 0);
227
228 /* Allocate new context structure */
229 if (NULL == (ctx = H5FL_MALLOC(H5D_farray_ctx_t)))
230 HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, NULL, "can't allocate fixed array client callback context")
231
232 /* Initialize the context */
233 ctx->file_addr_len = H5F_SIZEOF_ADDR(udata->f);
234
235 /* Compute the size required for encoding the size of a chunk, allowing
236 * for an extra byte, in case the filter makes the chunk larger.
237 */
238 ctx->chunk_size_len = 1 + ((H5VM_log2_gen((uint64_t)udata->chunk_size) + 8) / 8);
239 if (ctx->chunk_size_len > 8)
240 ctx->chunk_size_len = 8;
241
242 /* Set return value */
243 ret_value = ctx;
244
245 done:
246 FUNC_LEAVE_NOAPI(ret_value)
247 } /* end H5D__farray_crt_context() */
248
249 /*-------------------------------------------------------------------------
250 * Function: H5D__farray_dst_context
251 *
252 * Purpose: Destroy context for callbacks
253 *
254 * Return: Success: non-NULL
255 * Failure: NULL
256 *
257 * Programmer: Vailin Choi
258 * Thursday, April 30, 2009
259 *
260 *-------------------------------------------------------------------------
261 */
262 static herr_t
H5D__farray_dst_context(void * _ctx)263 H5D__farray_dst_context(void *_ctx)
264 {
265 H5D_farray_ctx_t *ctx = (H5D_farray_ctx_t *)_ctx; /* Fixed array callback context */
266
267 FUNC_ENTER_STATIC_NOERR
268
269 /* Sanity checks */
270 HDassert(ctx);
271
272 /* Release context structure */
273 ctx = H5FL_FREE(H5D_farray_ctx_t, ctx);
274
275 FUNC_LEAVE_NOAPI(SUCCEED)
276 } /* end H5D__farray_dst_context() */
277
278 /*-------------------------------------------------------------------------
279 * Function: H5D__farray_fill
280 *
281 * Purpose: Fill "missing elements" in block of elements
282 *
283 * Return: Success: non-negative
284 * Failure: negative
285 *
286 * Programmer: Vailin Choi
287 * Thursday, April 30, 2009
288 *
289 *-------------------------------------------------------------------------
290 */
291 static herr_t
H5D__farray_fill(void * nat_blk,size_t nelmts)292 H5D__farray_fill(void *nat_blk, size_t nelmts)
293 {
294 haddr_t fill_val = H5D_FARRAY_FILL; /* Value to fill elements with */
295
296 FUNC_ENTER_STATIC_NOERR
297
298 /* Sanity checks */
299 HDassert(nat_blk);
300 HDassert(nelmts);
301
302 H5VM_array_fill(nat_blk, &fill_val, H5FA_CLS_CHUNK->nat_elmt_size, nelmts);
303
304 FUNC_LEAVE_NOAPI(SUCCEED)
305 } /* end H5D__farray_fill() */
306
307 /*-------------------------------------------------------------------------
308 * Function: H5D__farray_encode
309 *
310 * Purpose: Encode an element from "native" to "raw" form
311 *
312 * Return: Success: non-negative
313 * Failure: negative
314 *
315 * Programmer: Vailin Choi
316 * Thursday, April 30, 2009
317 *
318 *-------------------------------------------------------------------------
319 */
320 static herr_t
H5D__farray_encode(void * raw,const void * _elmt,size_t nelmts,void * _ctx)321 H5D__farray_encode(void *raw, const void *_elmt, size_t nelmts, void *_ctx)
322 {
323 H5D_farray_ctx_t *ctx = (H5D_farray_ctx_t *)_ctx; /* Fixed array callback context */
324 const haddr_t * elmt = (const haddr_t *)_elmt; /* Convenience pointer to native elements */
325
326 FUNC_ENTER_STATIC_NOERR
327
328 /* Sanity checks */
329 HDassert(raw);
330 HDassert(elmt);
331 HDassert(nelmts);
332 HDassert(ctx);
333
334 /* Encode native elements into raw elements */
335 while (nelmts) {
336 /* Encode element */
337 /* (advances 'raw' pointer) */
338 H5F_addr_encode_len(ctx->file_addr_len, (uint8_t **)&raw, *elmt);
339
340 /* Advance native element pointer */
341 elmt++;
342
343 /* Decrement # of elements to encode */
344 nelmts--;
345 } /* end while */
346
347 FUNC_LEAVE_NOAPI(SUCCEED)
348 } /* end H5D__farray_encode() */
349
350 /*-------------------------------------------------------------------------
351 * Function: H5D__farray_decode
352 *
353 * Purpose: Decode an element from "raw" to "native" form
354 *
355 * Return: Success: non-negative
356 * Failure: negative
357 *
358 * Programmer: Vailin Choi
359 * Thursday, April 30, 2009
360 *
361 *-------------------------------------------------------------------------
362 */
363 static herr_t
H5D__farray_decode(const void * _raw,void * _elmt,size_t nelmts,void * _ctx)364 H5D__farray_decode(const void *_raw, void *_elmt, size_t nelmts, void *_ctx)
365 {
366 H5D_farray_ctx_t *ctx = (H5D_farray_ctx_t *)_ctx; /* Fixed array callback context */
367 haddr_t * elmt = (haddr_t *)_elmt; /* Convenience pointer to native elements */
368 const uint8_t * raw = (const uint8_t *)_raw; /* Convenience pointer to raw elements */
369
370 FUNC_ENTER_STATIC_NOERR
371
372 /* Sanity checks */
373 HDassert(raw);
374 HDassert(elmt);
375 HDassert(nelmts);
376
377 /* Decode raw elements into native elements */
378 while (nelmts) {
379 /* Decode element */
380 /* (advances 'raw' pointer) */
381 H5F_addr_decode_len(ctx->file_addr_len, &raw, elmt);
382
383 /* Advance native element pointer */
384 elmt++;
385
386 /* Decrement # of elements to decode */
387 nelmts--;
388 } /* end while */
389
390 FUNC_LEAVE_NOAPI(SUCCEED)
391 } /* end H5D__farray_decode() */
392
393 /*-------------------------------------------------------------------------
394 * Function: H5D__farray_debug
395 *
396 * Purpose: Display an element for debugging
397 *
398 * Return: Success: non-negative
399 * Failure: negative
400 *
401 * Programmer: Vailin Choi
402 * Thursday, April 30, 2009
403 *
404 *-------------------------------------------------------------------------
405 */
406 static herr_t
H5D__farray_debug(FILE * stream,int indent,int fwidth,hsize_t idx,const void * elmt)407 H5D__farray_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const void *elmt)
408 {
409 char temp_str[128]; /* Temporary string, for formatting */
410
411 FUNC_ENTER_STATIC_NOERR
412
413 /* Sanity checks */
414 HDassert(stream);
415 HDassert(elmt);
416
417 /* Print element */
418 HDsprintf(temp_str, "Element #%" PRIuHSIZE ":", idx);
419 HDfprintf(stream, "%*s%-*s %" PRIuHADDR "\n", indent, "", fwidth, temp_str, *(const haddr_t *)elmt);
420
421 FUNC_LEAVE_NOAPI(SUCCEED)
422 } /* end H5D__farray_debug() */
423
424 /*-------------------------------------------------------------------------
425 * Function: H5D__farray_crt_dbg_context
426 *
427 * Purpose: Create context for debugging callback
428 * (get the layout message in the specified object header)
429 *
430 * Return: Success: non-NULL
431 * Failure: NULL
432 *
433 * Programmer: Vailin Choi
434 * 5th August, 2009
435 *
436 *-------------------------------------------------------------------------
437 */
438 static void *
H5D__farray_crt_dbg_context(H5F_t * f,haddr_t obj_addr)439 H5D__farray_crt_dbg_context(H5F_t *f, haddr_t obj_addr)
440 {
441 H5D_farray_ctx_ud_t *dbg_ctx = NULL; /* Context for fixed array callback */
442 H5O_loc_t obj_loc; /* Pointer to an object's location */
443 hbool_t obj_opened = FALSE; /* Flag to indicate that the object header was opened */
444 H5O_layout_t layout; /* Layout message */
445 void * ret_value = NULL; /* Return value */
446
447 FUNC_ENTER_STATIC
448
449 /* Sanity checks */
450 HDassert(f);
451 HDassert(H5F_addr_defined(obj_addr));
452
453 /* Allocate context for debugging callback */
454 if (NULL == (dbg_ctx = H5FL_MALLOC(H5D_farray_ctx_ud_t)))
455 HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, NULL, "can't allocate fixed array client callback context")
456
457 /* Set up the object header location info */
458 H5O_loc_reset(&obj_loc);
459 obj_loc.file = f;
460 obj_loc.addr = obj_addr;
461
462 /* Open the object header where the layout message resides */
463 if (H5O_open(&obj_loc) < 0)
464 HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, NULL, "can't open object header")
465 obj_opened = TRUE;
466
467 /* Read the layout message */
468 if (NULL == H5O_msg_read(&obj_loc, H5O_LAYOUT_ID, &layout))
469 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't get layout info")
470
471 /* close the object header */
472 if (H5O_close(&obj_loc, NULL) < 0)
473 HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, NULL, "can't close object header")
474
475 /* Create user data */
476 dbg_ctx->f = f;
477 dbg_ctx->chunk_size = layout.u.chunk.size;
478
479 /* Set return value */
480 ret_value = dbg_ctx;
481
482 done:
483 /* Cleanup on error */
484 if (ret_value == NULL) {
485 /* Release context structure */
486 if (dbg_ctx)
487 dbg_ctx = H5FL_FREE(H5D_farray_ctx_ud_t, dbg_ctx);
488
489 /* Close object header */
490 if (obj_opened)
491 if (H5O_close(&obj_loc, NULL) < 0)
492 HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, NULL, "can't close object header")
493 } /* end if */
494
495 FUNC_LEAVE_NOAPI(ret_value)
496 } /* end H5D__farray_crt_dbg_context() */
497
498 /*-------------------------------------------------------------------------
499 * Function: H5D__farray_dst_dbg_context
500 *
501 * Purpose: Destroy context for debugging callback
502 * (free the layout message from the specified object header)
503 *
504 * Return: Success: non-negative
505 * Failure: negative
506 *
507 * Programmer: Quincey Koziol
508 * 24th September, 2009
509 *
510 *-------------------------------------------------------------------------
511 */
512 static herr_t
H5D__farray_dst_dbg_context(void * _dbg_ctx)513 H5D__farray_dst_dbg_context(void *_dbg_ctx)
514 {
515 H5D_farray_ctx_ud_t *dbg_ctx = (H5D_farray_ctx_ud_t *)_dbg_ctx; /* Context for fixed array callback */
516
517 FUNC_ENTER_STATIC_NOERR
518
519 /* Sanity checks */
520 HDassert(dbg_ctx);
521
522 /* Release context structure */
523 dbg_ctx = H5FL_FREE(H5D_farray_ctx_ud_t, dbg_ctx);
524
525 FUNC_LEAVE_NOAPI(SUCCEED)
526 } /* end H5D__farray_dst_dbg_context() */
527
528 /*-------------------------------------------------------------------------
529 * Function: H5D__farray_filt_fill
530 *
531 * Purpose: Fill "missing elements" in block of elements
532 *
533 * Return: Success: non-negative
534 * Failure: negative
535 *
536 * Programmer: Vailin Choi
537 * Thursday, April 30, 2009
538 *
539 *-------------------------------------------------------------------------
540 */
541 static herr_t
H5D__farray_filt_fill(void * nat_blk,size_t nelmts)542 H5D__farray_filt_fill(void *nat_blk, size_t nelmts)
543 {
544 H5D_farray_filt_elmt_t fill_val = H5D_FARRAY_FILT_FILL; /* Value to fill elements with */
545
546 FUNC_ENTER_STATIC_NOERR
547
548 /* Sanity checks */
549 HDassert(nat_blk);
550 HDassert(nelmts);
551 HDassert(sizeof(fill_val) == H5FA_CLS_FILT_CHUNK->nat_elmt_size);
552
553 H5VM_array_fill(nat_blk, &fill_val, H5FA_CLS_FILT_CHUNK->nat_elmt_size, nelmts);
554
555 FUNC_LEAVE_NOAPI(SUCCEED)
556 } /* end H5D__farray_filt_fill() */
557
558 /*-------------------------------------------------------------------------
559 * Function: H5D__farray_filt_encode
560 *
561 * Purpose: Encode an element from "native" to "raw" form
562 *
563 * Return: Success: non-negative
564 * Failure: negative
565 *
566 * Programmer: Vailin Choi
567 * Thursday, April 30, 2009
568 *
569 *-------------------------------------------------------------------------
570 */
571 static herr_t
H5D__farray_filt_encode(void * _raw,const void * _elmt,size_t nelmts,void * _ctx)572 H5D__farray_filt_encode(void *_raw, const void *_elmt, size_t nelmts, void *_ctx)
573 {
574 H5D_farray_ctx_t * ctx = (H5D_farray_ctx_t *)_ctx; /* Fixed array callback context */
575 uint8_t * raw = (uint8_t *)_raw; /* Convenience pointer to raw elements */
576 const H5D_farray_filt_elmt_t *elmt =
577 (const H5D_farray_filt_elmt_t *)_elmt; /* Convenience pointer to native elements */
578
579 FUNC_ENTER_STATIC_NOERR
580
581 /* Sanity checks */
582 HDassert(raw);
583 HDassert(elmt);
584 HDassert(nelmts);
585 HDassert(ctx);
586
587 /* Encode native elements into raw elements */
588 while (nelmts) {
589 /* Encode element */
590 /* (advances 'raw' pointer) */
591 H5F_addr_encode_len(ctx->file_addr_len, &raw, elmt->addr);
592 UINT64ENCODE_VAR(raw, elmt->nbytes, ctx->chunk_size_len);
593 UINT32ENCODE(raw, elmt->filter_mask);
594
595 /* Advance native element pointer */
596 elmt++;
597
598 /* Decrement # of elements to encode */
599 nelmts--;
600 } /* end while */
601
602 FUNC_LEAVE_NOAPI(SUCCEED)
603 } /* end H5D__farray_filt_encode() */
604
605 /*-------------------------------------------------------------------------
606 * Function: H5D__farray_filt_decode
607 *
608 * Purpose: Decode an element from "raw" to "native" form
609 *
610 * Return: Success: non-negative
611 * Failure: negative
612 *
613 * Programmer: Vailin Choi
614 * Thursday, April 30, 2009
615 *
616 *-------------------------------------------------------------------------
617 */
618 static herr_t
H5D__farray_filt_decode(const void * _raw,void * _elmt,size_t nelmts,void * _ctx)619 H5D__farray_filt_decode(const void *_raw, void *_elmt, size_t nelmts, void *_ctx)
620 {
621 H5D_farray_ctx_t * ctx = (H5D_farray_ctx_t *)_ctx; /* Fixed array callback context */
622 H5D_farray_filt_elmt_t *elmt =
623 (H5D_farray_filt_elmt_t *)_elmt; /* Convenience pointer to native elements */
624 const uint8_t *raw = (const uint8_t *)_raw; /* Convenience pointer to raw elements */
625
626 FUNC_ENTER_STATIC_NOERR
627
628 /* Sanity checks */
629 HDassert(raw);
630 HDassert(elmt);
631 HDassert(nelmts);
632
633 /* Decode raw elements into native elements */
634 while (nelmts) {
635 /* Decode element */
636 /* (advances 'raw' pointer) */
637 H5F_addr_decode_len(ctx->file_addr_len, &raw, &elmt->addr);
638 UINT64DECODE_VAR(raw, elmt->nbytes, ctx->chunk_size_len);
639 UINT32DECODE(raw, elmt->filter_mask);
640
641 /* Advance native element pointer */
642 elmt++;
643
644 /* Decrement # of elements to decode */
645 nelmts--;
646 } /* end while */
647
648 FUNC_LEAVE_NOAPI(SUCCEED)
649 } /* end H5D__farray_filt_decode() */
650
651 /*-------------------------------------------------------------------------
652 * Function: H5D__farray_filt_debug
653 *
654 * Purpose: Display an element for debugging
655 *
656 * Return: Success: non-negative
657 * Failure: negative
658 *
659 * Programmer: Vailin Choi
660 * Thursday, April 30, 2009
661 *
662 *-------------------------------------------------------------------------
663 */
664 static herr_t
H5D__farray_filt_debug(FILE * stream,int indent,int fwidth,hsize_t idx,const void * _elmt)665 H5D__farray_filt_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const void *_elmt)
666 {
667 const H5D_farray_filt_elmt_t *elmt =
668 (const H5D_farray_filt_elmt_t *)_elmt; /* Convenience pointer to native elements */
669 char temp_str[128]; /* Temporary string, for formatting */
670
671 FUNC_ENTER_STATIC_NOERR
672
673 /* Sanity checks */
674 HDassert(stream);
675 HDassert(elmt);
676
677 /* Print element */
678 HDsprintf(temp_str, "Element #%" PRIuHSIZE ":", idx);
679 HDfprintf(stream, "%*s%-*s {%" PRIuHADDR ", %u, %0x}\n", indent, "", fwidth, temp_str, elmt->addr,
680 elmt->nbytes, elmt->filter_mask);
681
682 FUNC_LEAVE_NOAPI(SUCCEED)
683 } /* end H5D__farray_filt_debug() */
684
685 /*-------------------------------------------------------------------------
686 * Function: H5D__farray_idx_depend
687 *
688 * Purpose: Create flush dependency between fixed array and dataset's
689 * object header.
690 *
691 * Return: Success: non-negative
692 * Failure: negative
693 *
694 * Programmer: Vailin Choi
695 * Thursday, April 30, 2009
696 *
697 *-------------------------------------------------------------------------
698 */
699 static herr_t
H5D__farray_idx_depend(const H5D_chk_idx_info_t * idx_info)700 H5D__farray_idx_depend(const H5D_chk_idx_info_t *idx_info)
701 {
702 H5O_t * oh = NULL; /* Object header */
703 H5O_loc_t oloc; /* Temporary object header location for dataset */
704 H5AC_proxy_entry_t *oh_proxy; /* Dataset's object header proxy */
705 herr_t ret_value = SUCCEED; /* Return value */
706
707 FUNC_ENTER_STATIC
708
709 /* Check args */
710 HDassert(idx_info);
711 HDassert(idx_info->f);
712 HDassert(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE);
713 HDassert(idx_info->pline);
714 HDassert(idx_info->layout);
715 HDassert(H5D_CHUNK_IDX_FARRAY == idx_info->layout->idx_type);
716 HDassert(idx_info->storage);
717 HDassert(H5D_CHUNK_IDX_FARRAY == idx_info->storage->idx_type);
718 HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
719 HDassert(idx_info->storage->u.farray.fa);
720
721 /* Set up object header location for dataset */
722 H5O_loc_reset(&oloc);
723 oloc.file = idx_info->f;
724 oloc.addr = idx_info->storage->u.farray.dset_ohdr_addr;
725
726 /* Get header */
727 if (NULL == (oh = H5O_protect(&oloc, H5AC__READ_ONLY_FLAG, TRUE)))
728 HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect object header")
729
730 /* Retrieve the dataset's object header proxy */
731 if (NULL == (oh_proxy = H5O_get_proxy(oh)))
732 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get dataset object header proxy")
733
734 /* Make the fixed array a child flush dependency of the dataset's object header proxy */
735 if (H5FA_depend(idx_info->storage->u.farray.fa, oh_proxy) < 0)
736 HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL,
737 "unable to create flush dependency on object header proxy")
738
739 done:
740 /* Release the object header from the cache */
741 if (oh && H5O_unprotect(&oloc, oh, H5AC__NO_FLAGS_SET) < 0)
742 HDONE_ERROR(H5E_DATASET, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
743
744 FUNC_LEAVE_NOAPI(ret_value)
745 } /* end H5D__farray_idx_depend() */
746
747 /*-------------------------------------------------------------------------
748 * Function: H5D__farray_idx_init
749 *
750 * Purpose: Initialize the indexing information for a dataset.
751 *
752 * Return: Non-negative on success/Negative on failure
753 *
754 * Programmer: Neil Fortner
755 * Wednensday, May 23, 2012
756 *
757 *-------------------------------------------------------------------------
758 */
759 static herr_t
H5D__farray_idx_init(const H5D_chk_idx_info_t * idx_info,const H5S_t H5_ATTR_UNUSED * space,haddr_t dset_ohdr_addr)760 H5D__farray_idx_init(const H5D_chk_idx_info_t *idx_info, const H5S_t H5_ATTR_UNUSED *space,
761 haddr_t dset_ohdr_addr)
762 {
763 FUNC_ENTER_STATIC_NOERR
764
765 /* Check args */
766 HDassert(idx_info);
767 HDassert(idx_info->storage);
768 HDassert(H5F_addr_defined(dset_ohdr_addr));
769
770 idx_info->storage->u.farray.dset_ohdr_addr = dset_ohdr_addr;
771
772 FUNC_LEAVE_NOAPI(SUCCEED)
773 } /* end H5D__farray_idx_init() */
774
775 /*-------------------------------------------------------------------------
776 * Function: H5D__farray_idx_open
777 *
778 * Purpose: Opens an existing fixed array and initializes
779 * the layout struct with information about the storage.
780 *
781 * Return: Success: non-negative
782 * Failure: negative
783 *
784 * Programmer: Vailin Choi
785 * Thursday, April 30, 2009
786 *
787 *-------------------------------------------------------------------------
788 */
789 static herr_t
H5D__farray_idx_open(const H5D_chk_idx_info_t * idx_info)790 H5D__farray_idx_open(const H5D_chk_idx_info_t *idx_info)
791 {
792 H5D_farray_ctx_ud_t udata; /* User data for fixed array open call */
793 herr_t ret_value = SUCCEED; /* Return value */
794
795 FUNC_ENTER_STATIC
796
797 /* Check args */
798 HDassert(idx_info);
799 HDassert(idx_info->f);
800 HDassert(idx_info->pline);
801 HDassert(idx_info->layout);
802 HDassert(H5D_CHUNK_IDX_FARRAY == idx_info->layout->idx_type);
803 HDassert(idx_info->storage);
804 HDassert(H5D_CHUNK_IDX_FARRAY == idx_info->storage->idx_type);
805 HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
806 HDassert(NULL == idx_info->storage->u.farray.fa);
807
808 /* Set up the user data */
809 udata.f = idx_info->f;
810 udata.chunk_size = idx_info->layout->size;
811
812 /* Open the fixed array for the chunk index */
813 if (NULL ==
814 (idx_info->storage->u.farray.fa = H5FA_open(idx_info->f, idx_info->storage->idx_addr, &udata)))
815 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open fixed array")
816
817 /* Check for SWMR writes to the file */
818 if (H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE)
819 if (H5D__farray_idx_depend(idx_info) < 0)
820 HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL,
821 "unable to create flush dependency on object header")
822
823 done:
824 FUNC_LEAVE_NOAPI(ret_value)
825 } /* end H5D__farray_idx_open() */
826
827 /*-------------------------------------------------------------------------
828 * Function: H5D__farray_idx_create
829 *
830 * Purpose: Creates a new indexed-storage fixed array and initializes
831 * the layout struct with information about the storage. The
832 * struct should be immediately written to the object header.
833 *
834 * This function must be called before passing LAYOUT to any of
835 * the other indexed storage functions!
836 *
837 * Return: Non-negative on success (with the LAYOUT argument initialized
838 * and ready to write to an object header). Negative on failure.
839 *
840 * Programmer: Vailin Choi
841 * Thursday, April 30, 2009
842 *
843 *-------------------------------------------------------------------------
844 */
845 static herr_t
H5D__farray_idx_create(const H5D_chk_idx_info_t * idx_info)846 H5D__farray_idx_create(const H5D_chk_idx_info_t *idx_info)
847 {
848 H5FA_create_t cparam; /* Fixed array creation parameters */
849 H5D_farray_ctx_ud_t udata; /* User data for fixed array create call */
850 herr_t ret_value = SUCCEED; /* Return value */
851
852 FUNC_ENTER_STATIC
853
854 /* Check args */
855 HDassert(idx_info);
856 HDassert(idx_info->f);
857 HDassert(idx_info->pline);
858 HDassert(idx_info->layout);
859 HDassert(idx_info->storage);
860 HDassert(!H5F_addr_defined(idx_info->storage->idx_addr));
861 HDassert(NULL == idx_info->storage->u.farray.fa);
862 HDassert(idx_info->layout->nchunks);
863
864 /* General parameters */
865 if (idx_info->pline->nused > 0) {
866 unsigned chunk_size_len; /* Size of encoded chunk size */
867
868 /* Compute the size required for encoding the size of a chunk, allowing
869 * for an extra byte, in case the filter makes the chunk larger.
870 */
871 chunk_size_len = 1 + ((H5VM_log2_gen((uint64_t)idx_info->layout->size) + 8) / 8);
872 if (chunk_size_len > 8)
873 chunk_size_len = 8;
874
875 cparam.cls = H5FA_CLS_FILT_CHUNK;
876 cparam.raw_elmt_size = (uint8_t)(H5F_SIZEOF_ADDR(idx_info->f) + chunk_size_len + 4);
877 } /* end if */
878 else {
879 cparam.cls = H5FA_CLS_CHUNK;
880 cparam.raw_elmt_size = (uint8_t)H5F_SIZEOF_ADDR(idx_info->f);
881 } /* end else */
882 cparam.max_dblk_page_nelmts_bits = idx_info->layout->u.farray.cparam.max_dblk_page_nelmts_bits;
883 HDassert(cparam.max_dblk_page_nelmts_bits > 0);
884 cparam.nelmts = idx_info->layout->max_nchunks;
885
886 /* Set up the user data */
887 udata.f = idx_info->f;
888 udata.chunk_size = idx_info->layout->size;
889
890 /* Create the fixed array for the chunk index */
891 if (NULL == (idx_info->storage->u.farray.fa = H5FA_create(idx_info->f, &cparam, &udata)))
892 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't create fixed array")
893
894 /* Get the address of the fixed array in file */
895 if (H5FA_get_addr(idx_info->storage->u.farray.fa, &(idx_info->storage->idx_addr)) < 0)
896 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't query fixed array address")
897
898 /* Check for SWMR writes to the file */
899 if (H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE)
900 if (H5D__farray_idx_depend(idx_info) < 0)
901 HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL,
902 "unable to create flush dependency on object header")
903
904 done:
905 FUNC_LEAVE_NOAPI(ret_value)
906 } /* end H5D__farray_idx_create() */
907
908 /*-------------------------------------------------------------------------
909 * Function: H5D__farray_idx_is_space_alloc
910 *
911 * Purpose: Query if space is allocated for index method
912 *
913 * Return: Non-negative on success/Negative on failure
914 *
915 * Programmer: Vailin Choi
916 * Thursday, April 30, 2009
917 *
918 *-------------------------------------------------------------------------
919 */
920 static hbool_t
H5D__farray_idx_is_space_alloc(const H5O_storage_chunk_t * storage)921 H5D__farray_idx_is_space_alloc(const H5O_storage_chunk_t *storage)
922 {
923 FUNC_ENTER_STATIC_NOERR
924
925 /* Check args */
926 HDassert(storage);
927
928 FUNC_LEAVE_NOAPI((hbool_t)H5F_addr_defined(storage->idx_addr))
929 } /* end H5D__farray_idx_is_space_alloc() */
930
931 /*-------------------------------------------------------------------------
932 * Function: H5D__farray_idx_insert
933 *
934 * Purpose: Insert chunk address into the indexing structure.
935 *
936 * Return: Non-negative on success/Negative on failure
937 *
938 * Programmer: Vailin Choi; 5 May 2014
939 *
940 *-------------------------------------------------------------------------
941 */
942 static herr_t
H5D__farray_idx_insert(const H5D_chk_idx_info_t * idx_info,H5D_chunk_ud_t * udata,const H5D_t H5_ATTR_UNUSED * dset)943 H5D__farray_idx_insert(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata,
944 const H5D_t H5_ATTR_UNUSED *dset)
945 {
946 H5FA_t *fa; /* Pointer to fixed array structure */
947 herr_t ret_value = SUCCEED; /* Return value */
948
949 FUNC_ENTER_STATIC
950
951 /* Sanity checks */
952 HDassert(idx_info);
953 HDassert(idx_info->f);
954 HDassert(idx_info->pline);
955 HDassert(idx_info->layout);
956 HDassert(idx_info->storage);
957 HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
958 HDassert(udata);
959
960 /* Check if the fixed array is open yet */
961 if (NULL == idx_info->storage->u.farray.fa) {
962 /* Open the fixed array in file */
963 if (H5D__farray_idx_open(idx_info) < 0)
964 HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open fixed array")
965 }
966 else /* Patch the top level file pointer contained in fa if needed */
967 H5FA_patch_file(idx_info->storage->u.farray.fa, idx_info->f);
968
969 /* Set convenience pointer to fixed array structure */
970 fa = idx_info->storage->u.farray.fa;
971
972 if (!H5F_addr_defined(udata->chunk_block.offset))
973 HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "The chunk should have allocated already")
974 if (udata->chunk_idx != (udata->chunk_idx & 0xffffffff)) /* negative value */
975 HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "chunk index must be less than 2^32")
976
977 /* Check for filters on chunks */
978 if (idx_info->pline->nused > 0) {
979 H5D_farray_filt_elmt_t elmt; /* Fixed array element */
980
981 elmt.addr = udata->chunk_block.offset;
982 H5_CHECKED_ASSIGN(elmt.nbytes, uint32_t, udata->chunk_block.length, hsize_t);
983 elmt.filter_mask = udata->filter_mask;
984
985 /* Set the info for the chunk */
986 if (H5FA_set(fa, udata->chunk_idx, &elmt) < 0)
987 HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set chunk info")
988 } /* end if */
989 else {
990 /* Set the address for the chunk */
991 if (H5FA_set(fa, udata->chunk_idx, &udata->chunk_block.offset) < 0)
992 HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set chunk address")
993 } /* end else */
994
995 done:
996 FUNC_LEAVE_NOAPI(ret_value)
997 } /* H5D__farray_idx_insert() */
998
999 /*-------------------------------------------------------------------------
1000 * Function: H5D__farray_idx_get_addr
1001 *
1002 * Purpose: Get the file address of a chunk if file space has been
1003 * assigned. Save the retrieved information in the udata
1004 * supplied.
1005 *
1006 * Return: Non-negative on success/Negative on failure
1007 *
1008 * Programmer: Vailin Choi
1009 * Thursday, April 30, 2009
1010 *
1011 *-------------------------------------------------------------------------
1012 */
1013 static herr_t
H5D__farray_idx_get_addr(const H5D_chk_idx_info_t * idx_info,H5D_chunk_ud_t * udata)1014 H5D__farray_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
1015 {
1016 H5FA_t *fa; /* Pointer to fixed array structure */
1017 hsize_t idx; /* Array index of chunk */
1018 herr_t ret_value = SUCCEED; /* Return value */
1019
1020 FUNC_ENTER_STATIC
1021
1022 /* Sanity checks */
1023 HDassert(idx_info);
1024 HDassert(idx_info->f);
1025 HDassert(idx_info->pline);
1026 HDassert(idx_info->layout);
1027 HDassert(idx_info->storage);
1028 HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
1029 HDassert(udata);
1030
1031 /* Check if the fixed array is open yet */
1032 if (NULL == idx_info->storage->u.farray.fa) {
1033 /* Open the fixed array in file */
1034 if (H5D__farray_idx_open(idx_info) < 0)
1035 HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open fixed array")
1036 }
1037 else /* Patch the top level file pointer contained in fa if needed */
1038 H5FA_patch_file(idx_info->storage->u.farray.fa, idx_info->f);
1039
1040 /* Set convenience pointer to fixed array structure */
1041 fa = idx_info->storage->u.farray.fa;
1042
1043 /* Calculate the index of this chunk */
1044 idx = H5VM_array_offset_pre((idx_info->layout->ndims - 1), idx_info->layout->max_down_chunks,
1045 udata->common.scaled);
1046
1047 udata->chunk_idx = idx;
1048
1049 /* Check for filters on chunks */
1050 if (idx_info->pline->nused > 0) {
1051 H5D_farray_filt_elmt_t elmt; /* Fixed array element */
1052
1053 /* Get the information for the chunk */
1054 if (H5FA_get(fa, idx, &elmt) < 0)
1055 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info")
1056
1057 /* Set the info for the chunk */
1058 udata->chunk_block.offset = elmt.addr;
1059 udata->chunk_block.length = elmt.nbytes;
1060 udata->filter_mask = elmt.filter_mask;
1061 } /* end if */
1062 else {
1063 /* Get the address for the chunk */
1064 if (H5FA_get(fa, idx, &udata->chunk_block.offset) < 0)
1065 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address")
1066
1067 /* Update the other (constant) information for the chunk */
1068 udata->chunk_block.length = idx_info->layout->size;
1069 udata->filter_mask = 0;
1070 } /* end else */
1071
1072 if (!H5F_addr_defined(udata->chunk_block.offset))
1073 udata->chunk_block.length = 0;
1074
1075 done:
1076 FUNC_LEAVE_NOAPI(ret_value)
1077 } /* H5D__farray_idx_get_addr() */
1078
1079 /*-------------------------------------------------------------------------
1080 * Function: H5D__farray_idx_iterate_cb
1081 *
1082 * Purpose: Callback routine for fixed array element iteration.
1083 *
1084 * Return: Non-negative on success/Negative on failure
1085 *
1086 * Programmer: Vailin Choi
1087 * Thursday, April 30, 2009
1088 *
1089 *-------------------------------------------------------------------------
1090 */
1091 static int
H5D__farray_idx_iterate_cb(hsize_t H5_ATTR_UNUSED idx,const void * _elmt,void * _udata)1092 H5D__farray_idx_iterate_cb(hsize_t H5_ATTR_UNUSED idx, const void *_elmt, void *_udata)
1093 {
1094 H5D_farray_it_ud_t *udata = (H5D_farray_it_ud_t *)_udata; /* User data */
1095 unsigned ndims; /* Rank of chunk */
1096 int curr_dim; /* Current dimension */
1097 int ret_value = H5_ITER_CONT; /* Return value */
1098
1099 FUNC_ENTER_STATIC_NOERR
1100
1101 /* Compose generic chunk record for callback */
1102 if (udata->filtered) {
1103 const H5D_farray_filt_elmt_t *filt_elmt = (const H5D_farray_filt_elmt_t *)_elmt;
1104
1105 udata->chunk_rec.chunk_addr = filt_elmt->addr;
1106 udata->chunk_rec.nbytes = filt_elmt->nbytes;
1107 udata->chunk_rec.filter_mask = filt_elmt->filter_mask;
1108 } /* end if */
1109 else
1110 udata->chunk_rec.chunk_addr = *(const haddr_t *)_elmt;
1111
1112 /* Make "generic chunk" callback */
1113 if (H5F_addr_defined(udata->chunk_rec.chunk_addr))
1114 if ((ret_value = (udata->cb)(&udata->chunk_rec, udata->udata)) < 0)
1115 HERROR(H5E_DATASET, H5E_CALLBACK, "failure in generic chunk iterator callback");
1116
1117 /* Update coordinates of chunk in dataset */
1118 ndims = udata->common.layout->ndims - 1;
1119 HDassert(ndims > 0);
1120 curr_dim = (int)(ndims - 1);
1121 while (curr_dim >= 0) {
1122 /* Increment coordinate in current dimension */
1123 udata->chunk_rec.scaled[curr_dim]++;
1124
1125 /* Check if we went off the end of the current dimension */
1126 if (udata->chunk_rec.scaled[curr_dim] >= udata->common.layout->max_chunks[curr_dim]) {
1127 /* Reset coordinate & move to next faster dimension */
1128 udata->chunk_rec.scaled[curr_dim] = 0;
1129 curr_dim--;
1130 } /* end if */
1131 else
1132 break;
1133 } /* end while */
1134
1135 FUNC_LEAVE_NOAPI(ret_value)
1136 } /* H5D__farray_idx_iterate_cb() */
1137
1138 /*-------------------------------------------------------------------------
1139 * Function: H5D__farray_idx_iterate
1140 *
1141 * Purpose: Iterate over the chunks in an index, making a callback
1142 * for each one.
1143 *
1144 * Return: Non-negative on success/Negative on failure
1145 *
1146 * Programmer: Vailin Choi
1147 * Thursday, April 30, 2009
1148 *
1149 *-------------------------------------------------------------------------
1150 */
1151 static int
H5D__farray_idx_iterate(const H5D_chk_idx_info_t * idx_info,H5D_chunk_cb_func_t chunk_cb,void * chunk_udata)1152 H5D__farray_idx_iterate(const H5D_chk_idx_info_t *idx_info, H5D_chunk_cb_func_t chunk_cb, void *chunk_udata)
1153 {
1154 H5FA_t * fa; /* Pointer to fixed array structure */
1155 H5FA_stat_t fa_stat; /* Fixed array statistics */
1156 int ret_value = FAIL; /* Return value */
1157
1158 FUNC_ENTER_STATIC
1159
1160 /* Sanity checks */
1161 HDassert(idx_info);
1162 HDassert(idx_info->f);
1163 HDassert(idx_info->pline);
1164 HDassert(idx_info->layout);
1165 HDassert(idx_info->storage);
1166 HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
1167 HDassert(chunk_cb);
1168 HDassert(chunk_udata);
1169
1170 /* Check if the fixed array is open yet */
1171 if (NULL == idx_info->storage->u.farray.fa) {
1172 /* Open the fixed array in file */
1173 if (H5D__farray_idx_open(idx_info) < 0)
1174 HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open fixed array")
1175 }
1176 else /* Patch the top level file pointer contained in fa if needed */
1177 H5FA_patch_file(idx_info->storage->u.farray.fa, idx_info->f);
1178
1179 /* Set convenience pointer to fixed array structure */
1180 fa = idx_info->storage->u.farray.fa;
1181
1182 /* Get the fixed array statistics */
1183 if (H5FA_get_stats(fa, &fa_stat) < 0)
1184 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't query fixed array statistics")
1185
1186 /* Check if there are any array elements */
1187 if (fa_stat.nelmts > 0) {
1188 H5D_farray_it_ud_t udata; /* User data for iteration callback */
1189
1190 /* Initialize userdata */
1191 HDmemset(&udata, 0, sizeof udata);
1192 udata.common.layout = idx_info->layout;
1193 udata.common.storage = idx_info->storage;
1194 HDmemset(&udata.chunk_rec, 0, sizeof(udata.chunk_rec));
1195 udata.filtered = (idx_info->pline->nused > 0);
1196 if (!udata.filtered) {
1197 udata.chunk_rec.nbytes = idx_info->layout->size;
1198 udata.chunk_rec.filter_mask = 0;
1199 } /* end if */
1200 udata.cb = chunk_cb;
1201 udata.udata = chunk_udata;
1202
1203 /* Iterate over the fixed array elements */
1204 if ((ret_value = H5FA_iterate(fa, H5D__farray_idx_iterate_cb, &udata)) < 0)
1205 HERROR(H5E_DATASET, H5E_BADITER, "unable to iterate over fixed array chunk index");
1206 } /* end if */
1207
1208 done:
1209 FUNC_LEAVE_NOAPI(ret_value)
1210 } /* end H5D__farray_idx_iterate() */
1211
1212 /*-------------------------------------------------------------------------
1213 * Function: H5D__farray_idx_remove
1214 *
1215 * Purpose: Remove chunk from index.
1216 *
1217 * Return: Non-negative on success/Negative on failure
1218 *
1219 * Programmer: Vailin Choi
1220 * Thursday, April 30, 2009
1221 *
1222 *-------------------------------------------------------------------------
1223 */
1224 static herr_t
H5D__farray_idx_remove(const H5D_chk_idx_info_t * idx_info,H5D_chunk_common_ud_t * udata)1225 H5D__farray_idx_remove(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata)
1226 {
1227 H5FA_t *fa; /* Pointer to fixed array structure */
1228 hsize_t idx; /* Array index of chunk */
1229 herr_t ret_value = SUCCEED; /* Return value */
1230
1231 FUNC_ENTER_STATIC
1232
1233 /* Sanity checks */
1234 HDassert(idx_info);
1235 HDassert(idx_info->f);
1236 HDassert(idx_info->pline);
1237 HDassert(idx_info->layout);
1238 HDassert(idx_info->storage);
1239 HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
1240 HDassert(udata);
1241
1242 /* Check if the fixed array is open yet */
1243 if (NULL == idx_info->storage->u.farray.fa) {
1244 /* Open the fixed array in file */
1245 if (H5D__farray_idx_open(idx_info) < 0)
1246 HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open fixed array")
1247 }
1248 else /* Patch the top level file pointer contained in fa if needed */
1249 if (H5FA_patch_file(idx_info->storage->u.farray.fa, idx_info->f) < 0)
1250 HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't patch fixed array file pointer")
1251
1252 /* Set convenience pointer to fixed array structure */
1253 fa = idx_info->storage->u.farray.fa;
1254
1255 /* Calculate the index of this chunk */
1256 idx = H5VM_array_offset_pre((idx_info->layout->ndims - 1), idx_info->layout->max_down_chunks,
1257 udata->scaled);
1258
1259 /* Check for filters on chunks */
1260 if (idx_info->pline->nused > 0) {
1261 H5D_farray_filt_elmt_t elmt; /* Fixed array element */
1262
1263 /* Get the info about the chunk for the index */
1264 if (H5FA_get(fa, idx, &elmt) < 0)
1265 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info")
1266
1267 /* Remove raw data chunk from file if not doing SWMR writes */
1268 HDassert(H5F_addr_defined(elmt.addr));
1269 if (!(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE)) {
1270 H5_CHECK_OVERFLOW(elmt.nbytes, /*From: */ uint32_t, /*To: */ hsize_t);
1271 if (H5MF_xfree(idx_info->f, H5FD_MEM_DRAW, elmt.addr, (hsize_t)elmt.nbytes) < 0)
1272 HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to free chunk")
1273 } /* end if */
1274
1275 /* Reset the info about the chunk for the index */
1276 elmt.addr = HADDR_UNDEF;
1277 elmt.nbytes = 0;
1278 elmt.filter_mask = 0;
1279 if (H5FA_set(fa, idx, &elmt) < 0)
1280 HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to reset chunk info")
1281 } /* end if */
1282 else {
1283 haddr_t addr = HADDR_UNDEF; /* Chunk address */
1284
1285 /* Get the address of the chunk for the index */
1286 if (H5FA_get(fa, idx, &addr) < 0)
1287 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address")
1288
1289 /* Remove raw data chunk from file if not doing SWMR writes */
1290 HDassert(H5F_addr_defined(addr));
1291 if (!(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE)) {
1292 H5_CHECK_OVERFLOW(idx_info->layout->size, /*From: */ uint32_t, /*To: */ hsize_t);
1293 if (H5MF_xfree(idx_info->f, H5FD_MEM_DRAW, addr, (hsize_t)idx_info->layout->size) < 0)
1294 HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to free chunk")
1295 } /* end if */
1296
1297 /* Reset the address of the chunk for the index */
1298 addr = HADDR_UNDEF;
1299 if (H5FA_set(fa, idx, &addr) < 0)
1300 HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to reset chunk address")
1301 } /* end else */
1302
1303 done:
1304 FUNC_LEAVE_NOAPI(ret_value)
1305 } /* H5D__farray_idx_remove() */
1306
1307 /*-------------------------------------------------------------------------
1308 * Function: H5D__farray_idx_delete_cb
1309 *
1310 * Purpose: Delete space for chunk in file
1311 *
1312 * Return: Success: Non-negative
1313 * Failure: negative
1314 *
1315 * Programmer: Vailin Choi
1316 * Thursday, April 30, 2009
1317 *
1318 *-------------------------------------------------------------------------
1319 */
1320 static int
H5D__farray_idx_delete_cb(const H5D_chunk_rec_t * chunk_rec,void * _udata)1321 H5D__farray_idx_delete_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
1322 {
1323 H5F_t *f = (H5F_t *)_udata; /* User data for callback */
1324 int ret_value = H5_ITER_CONT; /* Return value */
1325
1326 FUNC_ENTER_STATIC
1327
1328 /* Sanity checks */
1329 HDassert(chunk_rec);
1330 HDassert(H5F_addr_defined(chunk_rec->chunk_addr));
1331 HDassert(chunk_rec->nbytes > 0);
1332 HDassert(f);
1333
1334 /* Remove raw data chunk from file */
1335 H5_CHECK_OVERFLOW(chunk_rec->nbytes, /*From: */ uint32_t, /*To: */ hsize_t);
1336 if (H5MF_xfree(f, H5FD_MEM_DRAW, chunk_rec->chunk_addr, (hsize_t)chunk_rec->nbytes) < 0)
1337 HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, H5_ITER_ERROR, "unable to free chunk")
1338
1339 done:
1340 FUNC_LEAVE_NOAPI(ret_value)
1341 } /* end H5D__farray_idx_delete_cb() */
1342
1343 /*-------------------------------------------------------------------------
1344 * Function: H5D__farray_idx_delete
1345 *
1346 * Purpose: Delete index and raw data storage for entire dataset
1347 * (i.e. all chunks)
1348 *
1349 * Return: Success: Non-negative
1350 * Failure: negative
1351 *
1352 * Programmer: Vailin Choi
1353 * Thursday, April 30, 2009
1354 *
1355 *-------------------------------------------------------------------------
1356 */
1357 static herr_t
H5D__farray_idx_delete(const H5D_chk_idx_info_t * idx_info)1358 H5D__farray_idx_delete(const H5D_chk_idx_info_t *idx_info)
1359 {
1360 herr_t ret_value = SUCCEED; /* Return value */
1361
1362 FUNC_ENTER_STATIC
1363
1364 /* Sanity checks */
1365 HDassert(idx_info);
1366 HDassert(idx_info->f);
1367 HDassert(idx_info->pline);
1368 HDassert(idx_info->layout);
1369 HDassert(idx_info->storage);
1370
1371 /* Check if the index data structure has been allocated */
1372 if (H5F_addr_defined(idx_info->storage->idx_addr)) {
1373 H5D_farray_ctx_ud_t ctx_udata; /* User data for fixed array open call */
1374
1375 /* Iterate over the chunk addresses in the fixed array, deleting each chunk */
1376 if (H5D__farray_idx_iterate(idx_info, H5D__farray_idx_delete_cb, idx_info->f) < 0)
1377 HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to iterate over chunk addresses")
1378
1379 /* Close fixed array */
1380 if (H5FA_close(idx_info->storage->u.farray.fa) < 0)
1381 HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close fixed array")
1382 idx_info->storage->u.farray.fa = NULL;
1383
1384 /* Set up the user data */
1385 ctx_udata.f = idx_info->f;
1386 ctx_udata.chunk_size = idx_info->layout->size;
1387
1388 /* Delete fixed array */
1389 if (H5FA_delete(idx_info->f, idx_info->storage->idx_addr, &ctx_udata) < 0)
1390 HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete chunk fixed array")
1391 idx_info->storage->idx_addr = HADDR_UNDEF;
1392 } /* end if */
1393 else
1394 HDassert(NULL == idx_info->storage->u.farray.fa);
1395
1396 done:
1397 FUNC_LEAVE_NOAPI(ret_value)
1398 } /* end H5D__farray_idx_delete() */
1399
1400 /*-------------------------------------------------------------------------
1401 * Function: H5D__farray_idx_copy_setup
1402 *
1403 * Purpose: Set up any necessary information for copying chunks
1404 *
1405 * Return: Non-negative on success/Negative on failure
1406 *
1407 * Programmer: Vailin Choi
1408 * Thursday, April 30, 2009
1409 *
1410 *-------------------------------------------------------------------------
1411 */
1412 static herr_t
H5D__farray_idx_copy_setup(const H5D_chk_idx_info_t * idx_info_src,const H5D_chk_idx_info_t * idx_info_dst)1413 H5D__farray_idx_copy_setup(const H5D_chk_idx_info_t *idx_info_src, const H5D_chk_idx_info_t *idx_info_dst)
1414 {
1415 herr_t ret_value = SUCCEED; /* Return value */
1416
1417 FUNC_ENTER_STATIC
1418
1419 /* Check args */
1420 HDassert(idx_info_src);
1421 HDassert(idx_info_src->f);
1422 HDassert(idx_info_src->pline);
1423 HDassert(idx_info_src->layout);
1424 HDassert(idx_info_src->storage);
1425 HDassert(idx_info_dst);
1426 HDassert(idx_info_dst->f);
1427 HDassert(idx_info_dst->pline);
1428 HDassert(idx_info_dst->layout);
1429 HDassert(idx_info_dst->storage);
1430 HDassert(!H5F_addr_defined(idx_info_dst->storage->idx_addr));
1431
1432 /* Check if the source fixed array is open yet */
1433 if (NULL == idx_info_src->storage->u.farray.fa)
1434 /* Open the fixed array in file */
1435 if (H5D__farray_idx_open(idx_info_src) < 0)
1436 HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open fixed array")
1437
1438 /* Set copied metadata tag */
1439 H5_BEGIN_TAG(H5AC__COPIED_TAG);
1440
1441 /* Create the fixed array that describes chunked storage in the dest. file */
1442 if (H5D__farray_idx_create(idx_info_dst) < 0)
1443 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize chunked storage")
1444 HDassert(H5F_addr_defined(idx_info_dst->storage->idx_addr));
1445
1446 /* Reset metadata tag */
1447 H5_END_TAG
1448
1449 done:
1450 FUNC_LEAVE_NOAPI(ret_value)
1451 } /* end H5D__farray_idx_copy_setup() */
1452
1453 /*-------------------------------------------------------------------------
1454 * Function: H5D__farray_idx_copy_shutdown
1455 *
1456 * Purpose: Shutdown any information from copying chunks
1457 *
1458 * Return: Non-negative on success/Negative on failure
1459 *
1460 * Programmer: Vailin Choi
1461 * Thursday, April 30, 2009
1462 *
1463 *-------------------------------------------------------------------------
1464 */
1465 static herr_t
H5D__farray_idx_copy_shutdown(H5O_storage_chunk_t * storage_src,H5O_storage_chunk_t * storage_dst)1466 H5D__farray_idx_copy_shutdown(H5O_storage_chunk_t *storage_src, H5O_storage_chunk_t *storage_dst)
1467 {
1468 herr_t ret_value = SUCCEED; /* Return value */
1469
1470 FUNC_ENTER_STATIC
1471
1472 /* Check args */
1473 HDassert(storage_src);
1474 HDassert(storage_src->u.farray.fa);
1475 HDassert(storage_dst);
1476 HDassert(storage_dst->u.farray.fa);
1477
1478 /* Close fixed arrays */
1479 if (H5FA_close(storage_src->u.farray.fa) < 0)
1480 HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close fixed array")
1481 storage_src->u.farray.fa = NULL;
1482 if (H5FA_close(storage_dst->u.farray.fa) < 0)
1483 HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close fixed array")
1484 storage_dst->u.farray.fa = NULL;
1485
1486 done:
1487 FUNC_LEAVE_NOAPI(ret_value)
1488 } /* end H5D__farray_idx_copy_shutdown() */
1489
1490 /*-------------------------------------------------------------------------
1491 * Function: H5D__farray_idx_size
1492 *
1493 * Purpose: Retrieve the amount of index storage for chunked dataset
1494 *
1495 * Return: Success: Non-negative
1496 * Failure: negative
1497 *
1498 * Programmer: Vailin Choi
1499 * Thursday, April 30, 2009
1500 *
1501 *-------------------------------------------------------------------------
1502 */
1503 static herr_t
H5D__farray_idx_size(const H5D_chk_idx_info_t * idx_info,hsize_t * index_size)1504 H5D__farray_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *index_size)
1505 {
1506 H5FA_t * fa; /* Pointer to fixed array structure */
1507 H5FA_stat_t fa_stat; /* Fixed array statistics */
1508 herr_t ret_value = SUCCEED; /* Return value */
1509
1510 FUNC_ENTER_STATIC
1511
1512 /* Check args */
1513 HDassert(idx_info);
1514 HDassert(idx_info->f);
1515 HDassert(idx_info->pline);
1516 HDassert(idx_info->layout);
1517 HDassert(idx_info->storage);
1518 HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
1519 HDassert(index_size);
1520
1521 /* Open the fixed array in file */
1522 if (H5D__farray_idx_open(idx_info) < 0)
1523 HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open fixed array")
1524
1525 /* Set convenience pointer to fixed array structure */
1526 fa = idx_info->storage->u.farray.fa;
1527
1528 /* Get the fixed array statistics */
1529 if (H5FA_get_stats(fa, &fa_stat) < 0)
1530 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't query fixed array statistics")
1531
1532 *index_size = fa_stat.hdr_size;
1533 *index_size += fa_stat.dblk_size;
1534
1535 done:
1536 if (idx_info->storage->u.farray.fa) {
1537 if (H5FA_close(idx_info->storage->u.farray.fa) < 0)
1538 HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close fixed array")
1539 idx_info->storage->u.farray.fa = NULL;
1540 } /* end if */
1541
1542 FUNC_LEAVE_NOAPI(ret_value)
1543 } /* end H5D__farray_idx_size() */
1544
1545 /*-------------------------------------------------------------------------
1546 * Function: H5D__farray_idx_reset
1547 *
1548 * Purpose: Reset indexing information.
1549 *
1550 * Return: Non-negative on success/Negative on failure
1551 *
1552 * Programmer: Vailin Choi
1553 * Thursday, April 30, 2009
1554 *
1555 *-------------------------------------------------------------------------
1556 */
1557 static herr_t
H5D__farray_idx_reset(H5O_storage_chunk_t * storage,hbool_t reset_addr)1558 H5D__farray_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr)
1559 {
1560 FUNC_ENTER_STATIC_NOERR
1561
1562 /* Check args */
1563 HDassert(storage);
1564
1565 /* Reset index info */
1566 if (reset_addr)
1567 storage->idx_addr = HADDR_UNDEF;
1568 storage->u.farray.fa = NULL;
1569
1570 FUNC_LEAVE_NOAPI(SUCCEED)
1571 } /* end H5D__farray_idx_reset() */
1572
1573 /*-------------------------------------------------------------------------
1574 * Function: H5D__farray_idx_dump
1575 *
1576 * Purpose: Dump indexing information to a stream.
1577 *
1578 * Return: Non-negative on success/Negative on failure
1579 *
1580 * Programmer: Vailin Choi
1581 * Thursday, April 30, 2009
1582 *
1583 *-------------------------------------------------------------------------
1584 */
1585 static herr_t
H5D__farray_idx_dump(const H5O_storage_chunk_t * storage,FILE * stream)1586 H5D__farray_idx_dump(const H5O_storage_chunk_t *storage, FILE *stream)
1587 {
1588 FUNC_ENTER_STATIC_NOERR
1589
1590 /* Check args */
1591 HDassert(storage);
1592 HDassert(stream);
1593
1594 HDfprintf(stream, " Address: %" PRIuHADDR "\n", storage->idx_addr);
1595
1596 FUNC_LEAVE_NOAPI(SUCCEED)
1597 } /* end H5D__farray_idx_dump() */
1598
1599 /*-------------------------------------------------------------------------
1600 * Function: H5D__farray_idx_dest
1601 *
1602 * Purpose: Release indexing information in memory.
1603 *
1604 * Return: Non-negative on success/Negative on failure
1605 *
1606 * Programmer: Vailin Choi
1607 * Thursday, April 30, 2009
1608 *
1609 *-------------------------------------------------------------------------
1610 */
1611 static herr_t
H5D__farray_idx_dest(const H5D_chk_idx_info_t * idx_info)1612 H5D__farray_idx_dest(const H5D_chk_idx_info_t *idx_info)
1613 {
1614 herr_t ret_value = SUCCEED; /* Return value */
1615
1616 FUNC_ENTER_STATIC
1617
1618 /* Check args */
1619 HDassert(idx_info);
1620 HDassert(idx_info->f);
1621 HDassert(idx_info->storage);
1622
1623 /* Check if the fixed array is open */
1624 if (idx_info->storage->u.farray.fa) {
1625
1626 /* Patch the top level file pointer contained in fa if needed */
1627 if (H5FA_patch_file(idx_info->storage->u.farray.fa, idx_info->f) < 0)
1628 HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't patch fixed array file pointer")
1629
1630 /* Close fixed array */
1631 if (H5FA_close(idx_info->storage->u.farray.fa) < 0)
1632 HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close fixed array")
1633 idx_info->storage->u.farray.fa = NULL;
1634 } /* end if */
1635
1636 done:
1637 FUNC_LEAVE_NOAPI(ret_value)
1638 } /* end H5D__farray_idx_dest() */
1639