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