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