1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /*-------------------------------------------------------------------------
15 *
16 * Created: H5B2cache.c
17 * Jan 31 2005
18 * Quincey Koziol <koziol@hdfgroup.org>
19 *
20 * Purpose: Implement v2 B-tree metadata cache methods.
21 *
22 *-------------------------------------------------------------------------
23 */
24
25 /****************/
26 /* Module Setup */
27 /****************/
28
29 #define H5B2_PACKAGE /*suppress error about including H5B2pkg */
30
31
32 /***********/
33 /* Headers */
34 /***********/
35 #include "H5private.h" /* Generic Functions */
36 #include "H5B2pkg.h" /* v2 B-trees */
37 #include "H5Eprivate.h" /* Error handling */
38 #include "H5MFprivate.h" /* File memory management */
39 #include "H5WBprivate.h" /* Wrapped Buffers */
40
41
42 /****************/
43 /* Local Macros */
44 /****************/
45
46 /* B-tree format version #'s */
47 #define H5B2_HDR_VERSION 0 /* Header */
48 #define H5B2_INT_VERSION 0 /* Internal node */
49 #define H5B2_LEAF_VERSION 0 /* Leaf node */
50
51 /* Size of stack buffer for serialized headers */
52 #define H5B2_HDR_BUF_SIZE 128
53
54
55 /******************/
56 /* Local Typedefs */
57 /******************/
58
59
60 /********************/
61 /* Package Typedefs */
62 /********************/
63
64
65 /********************/
66 /* Local Prototypes */
67 /********************/
68
69 /* Metadata cache callbacks */
70 static H5B2_hdr_t *H5B2__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata);
71 static herr_t H5B2__cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_hdr_t *hdr, unsigned H5_ATTR_UNUSED * flags_ptr);
72 static herr_t H5B2__cache_hdr_dest(H5F_t *f, H5B2_hdr_t *hdr);
73 static herr_t H5B2__cache_hdr_clear(H5F_t *f, H5B2_hdr_t *hdr, hbool_t destroy);
74 static herr_t H5B2__cache_hdr_size(const H5F_t *f, const H5B2_hdr_t *hdr, size_t *size_ptr);
75 static H5B2_internal_t *H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata);
76 static herr_t H5B2__cache_internal_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_internal_t *i, unsigned H5_ATTR_UNUSED * flags_ptr);
77 static herr_t H5B2__cache_internal_dest(H5F_t *f, H5B2_internal_t *internal);
78 static herr_t H5B2__cache_internal_clear(H5F_t *f, H5B2_internal_t *i, hbool_t destroy);
79 static herr_t H5B2__cache_internal_size(const H5F_t *f, const H5B2_internal_t *i, size_t *size_ptr);
80 static H5B2_leaf_t *H5B2__cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata);
81 static herr_t H5B2__cache_leaf_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_leaf_t *l, unsigned H5_ATTR_UNUSED * flags_ptr);
82 static herr_t H5B2__cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf);
83 static herr_t H5B2__cache_leaf_clear(H5F_t *f, H5B2_leaf_t *l, hbool_t destroy);
84 static herr_t H5B2__cache_leaf_size(const H5F_t *f, const H5B2_leaf_t *l, size_t *size_ptr);
85
86
87 /*********************/
88 /* Package Variables */
89 /*********************/
90
91 /* H5B2 inherits cache-like properties from H5AC */
92 const H5AC_class_t H5AC_BT2_HDR[1] = {{
93 H5AC_BT2_HDR_ID,
94 (H5AC_load_func_t)H5B2__cache_hdr_load,
95 (H5AC_flush_func_t)H5B2__cache_hdr_flush,
96 (H5AC_dest_func_t)H5B2__cache_hdr_dest,
97 (H5AC_clear_func_t)H5B2__cache_hdr_clear,
98 (H5AC_size_func_t)H5B2__cache_hdr_size,
99 }};
100
101 /* H5B2 inherits cache-like properties from H5AC */
102 const H5AC_class_t H5AC_BT2_INT[1] = {{
103 H5AC_BT2_INT_ID,
104 (H5AC_load_func_t)H5B2__cache_internal_load,
105 (H5AC_flush_func_t)H5B2__cache_internal_flush,
106 (H5AC_dest_func_t)H5B2__cache_internal_dest,
107 (H5AC_clear_func_t)H5B2__cache_internal_clear,
108 (H5AC_size_func_t)H5B2__cache_internal_size,
109 }};
110
111 /* H5B2 inherits cache-like properties from H5AC */
112 const H5AC_class_t H5AC_BT2_LEAF[1] = {{
113 H5AC_BT2_LEAF_ID,
114 (H5AC_load_func_t)H5B2__cache_leaf_load,
115 (H5AC_flush_func_t)H5B2__cache_leaf_flush,
116 (H5AC_dest_func_t)H5B2__cache_leaf_dest,
117 (H5AC_clear_func_t)H5B2__cache_leaf_clear,
118 (H5AC_size_func_t)H5B2__cache_leaf_size,
119 }};
120
121
122 /*****************************/
123 /* Library Private Variables */
124 /*****************************/
125
126
127 /*******************/
128 /* Local Variables */
129 /*******************/
130
131
132
133 /*-------------------------------------------------------------------------
134 * Function: H5B2__cache_hdr_load
135 *
136 * Purpose: Loads a B-tree header from the disk.
137 *
138 * Return: Success: Pointer to a new B-tree.
139 * Failure: NULL
140 *
141 * Programmer: Quincey Koziol
142 * koziol@ncsa.uiuc.edu
143 * Feb 1 2005
144 *
145 *-------------------------------------------------------------------------
146 */
147 static H5B2_hdr_t *
H5B2__cache_hdr_load(H5F_t * f,hid_t dxpl_id,haddr_t addr,void * _udata)148 H5B2__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
149 {
150 H5B2_hdr_t *hdr = NULL; /* B-tree header */
151 H5B2_hdr_cache_ud_t *udata = (H5B2_hdr_cache_ud_t *)_udata;
152 H5B2_create_t cparam; /* B-tree creation parameters */
153 H5B2_subid_t id; /* ID of B-tree class, as found in file */
154 uint16_t depth; /* Depth of B-tree */
155 uint32_t stored_chksum; /* Stored metadata checksum value */
156 uint32_t computed_chksum; /* Computed metadata checksum value */
157 H5WB_t *wb = NULL; /* Wrapped buffer for header data */
158 uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */
159 uint8_t *buf; /* Pointer to header buffer */
160 const uint8_t *p; /* Pointer into raw data buffer */
161 H5B2_hdr_t *ret_value; /* Return value */
162
163 FUNC_ENTER_STATIC
164
165 /* Check arguments */
166 HDassert(f);
167 HDassert(H5F_addr_defined(addr));
168 HDassert(udata);
169
170 /* Allocate new B-tree header and reset cache info */
171 if(NULL == (hdr = H5B2_hdr_alloc(udata->f)))
172 HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "allocation failed for B-tree header")
173
174 /* Wrap the local buffer for serialized header info */
175 if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
176 HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't wrap buffer")
177
178 /* Get a pointer to a buffer that's large enough for header */
179 if(NULL == (buf = (uint8_t *)H5WB_actual(wb, hdr->hdr_size)))
180 HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "can't get actual buffer")
181
182 /* Read header from disk */
183 if(H5F_block_read(f, H5FD_MEM_BTREE, addr, hdr->hdr_size, dxpl_id, buf) < 0)
184 HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree header")
185
186 /* Get temporary pointer to serialized header */
187 p = buf;
188
189 /* Magic number */
190 if(HDmemcmp(p, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
191 HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "wrong B-tree header signature")
192 p += H5_SIZEOF_MAGIC;
193
194 /* Version */
195 if(*p++ != H5B2_HDR_VERSION)
196 HGOTO_ERROR(H5E_BTREE, H5E_BADRANGE, NULL, "wrong B-tree header version")
197
198 /* B-tree class */
199 id = (H5B2_subid_t)*p++;
200 if(id >= H5B2_NUM_BTREE_ID)
201 HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "incorrect B-tree type")
202
203 /* Node size (in bytes) */
204 UINT32DECODE(p, cparam.node_size);
205
206 /* Raw key size (in bytes) */
207 UINT16DECODE(p, cparam.rrec_size);
208
209 /* Depth of tree */
210 UINT16DECODE(p, depth);
211
212 /* Split & merge %s */
213 cparam.split_percent = *p++;
214 cparam.merge_percent = *p++;
215
216 /* Root node pointer */
217 H5F_addr_decode(udata->f, (const uint8_t **)&p, &(hdr->root.addr));
218 UINT16DECODE(p, hdr->root.node_nrec);
219 H5F_DECODE_LENGTH(udata->f, p, hdr->root.all_nrec);
220
221 /* Metadata checksum */
222 UINT32DECODE(p, stored_chksum);
223
224 /* Sanity check */
225 HDassert((size_t)(p - (const uint8_t *)buf) == hdr->hdr_size);
226
227 /* Compute checksum on entire header */
228 computed_chksum = H5_checksum_metadata(buf, (hdr->hdr_size - H5B2_SIZEOF_CHKSUM), 0);
229
230 /* Verify checksum */
231 if(stored_chksum != computed_chksum)
232 HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 B-tree header")
233
234 /* Initialize B-tree header info */
235 cparam.cls = H5B2_client_class_g[id];
236 if(H5B2_hdr_init(hdr, &cparam, udata->ctx_udata, depth) < 0)
237 HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't initialize B-tree header info")
238
239 /* Set the B-tree header's address */
240 hdr->addr = addr;
241
242 /* Set return value */
243 ret_value = hdr;
244
245 done:
246 /* Release resources */
247 if(wb && H5WB_unwrap(wb) < 0)
248 HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
249 if(!ret_value && hdr)
250 if(H5B2_hdr_free(hdr) < 0)
251 HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, NULL, "can't release v2 B-tree header")
252
253 FUNC_LEAVE_NOAPI(ret_value)
254 } /* end H5B2__cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */
255
256
257 /*-------------------------------------------------------------------------
258 * Function: H5B2__cache_hdr_flush
259 *
260 * Purpose: Flushes a dirty B-tree header to disk.
261 *
262 * Return: Non-negative on success/Negative on failure
263 *
264 * Programmer: Quincey Koziol
265 * koziol@ncsa.uiuc.edu
266 * Feb 1 2005
267 *
268 *-------------------------------------------------------------------------
269 */
270 static herr_t
H5B2__cache_hdr_flush(H5F_t * f,hid_t dxpl_id,hbool_t destroy,haddr_t addr,H5B2_hdr_t * hdr,unsigned H5_ATTR_UNUSED * flags_ptr)271 H5B2__cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
272 H5B2_hdr_t *hdr, unsigned H5_ATTR_UNUSED * flags_ptr)
273 {
274 H5WB_t *wb = NULL; /* Wrapped buffer for header data */
275 uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */
276 herr_t ret_value = SUCCEED; /* Return value */
277
278 FUNC_ENTER_STATIC
279
280 /* check arguments */
281 HDassert(f);
282 HDassert(H5F_addr_defined(addr));
283 HDassert(hdr);
284
285 if(hdr->cache_info.is_dirty) {
286 uint8_t *buf; /* Pointer to header buffer */
287 uint8_t *p; /* Pointer into raw data buffer */
288 uint32_t metadata_chksum; /* Computed metadata checksum value */
289
290 /* Set the B-tree header's file context for this operation */
291 hdr->f = f;
292
293 /* Wrap the local buffer for serialized header info */
294 if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
295 HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't wrap buffer")
296
297 /* Get a pointer to a buffer that's large enough for header */
298 if(NULL == (buf = (uint8_t *)H5WB_actual(wb, hdr->hdr_size)))
299 HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "can't get actual buffer")
300
301 /* Get temporary pointer to serialized header */
302 p = buf;
303
304 /* Magic number */
305 HDmemcpy(p, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
306 p += H5_SIZEOF_MAGIC;
307
308 /* Version # */
309 *p++ = H5B2_HDR_VERSION;
310
311 /* B-tree type */
312 *p++ = hdr->cls->id;
313
314 /* Node size (in bytes) */
315 UINT32ENCODE(p, hdr->node_size);
316
317 /* Raw key size (in bytes) */
318 UINT16ENCODE(p, hdr->rrec_size);
319
320 /* Depth of tree */
321 UINT16ENCODE(p, hdr->depth);
322
323 /* Split & merge %s */
324 H5_CHECK_OVERFLOW(hdr->split_percent, /* From: */ unsigned, /* To: */ uint8_t);
325 *p++ = (uint8_t)hdr->split_percent;
326 H5_CHECK_OVERFLOW(hdr->merge_percent, /* From: */ unsigned, /* To: */ uint8_t);
327 *p++ = (uint8_t)hdr->merge_percent;
328
329 /* Root node pointer */
330 H5F_addr_encode(f, &p, hdr->root.addr);
331 UINT16ENCODE(p, hdr->root.node_nrec);
332 H5F_ENCODE_LENGTH(f, p, hdr->root.all_nrec);
333
334 /* Compute metadata checksum */
335 metadata_chksum = H5_checksum_metadata(buf, (hdr->hdr_size - H5B2_SIZEOF_CHKSUM), 0);
336
337 /* Metadata checksum */
338 UINT32ENCODE(p, metadata_chksum);
339
340 /* Write the B-tree header. */
341 HDassert((size_t)(p - buf) == hdr->hdr_size);
342 if(H5F_block_write(f, H5FD_MEM_BTREE, addr, hdr->hdr_size, dxpl_id, buf) < 0)
343 HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree header to disk")
344
345 hdr->cache_info.is_dirty = FALSE;
346 } /* end if */
347
348 if(destroy)
349 if(H5B2__cache_hdr_dest(f, hdr) < 0)
350 HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header")
351
352 done:
353 /* Release resources */
354 if(wb && H5WB_unwrap(wb) < 0)
355 HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
356
357 FUNC_LEAVE_NOAPI(ret_value)
358 } /* H5B2__cache_hdr_flush() */
359
360
361 /*-------------------------------------------------------------------------
362 * Function: H5B2__cache_hdr_dest
363 *
364 * Purpose: Destroys a B-tree header in memory.
365 *
366 * Return: Non-negative on success/Negative on failure
367 *
368 * Programmer: Quincey Koziol
369 * koziol@ncsa.uiuc.edu
370 * Feb 1 2005
371 *
372 *-------------------------------------------------------------------------
373 */
374 static herr_t
H5B2__cache_hdr_dest(H5F_t * f,H5B2_hdr_t * hdr)375 H5B2__cache_hdr_dest(H5F_t *f, H5B2_hdr_t *hdr)
376 {
377 herr_t ret_value = SUCCEED; /* Return value */
378
379 FUNC_ENTER_STATIC
380
381 /* Check arguments */
382 HDassert(hdr);
383 HDassert(hdr->rc == 0);
384
385 /* If we're going to free the space on disk, the address must be valid */
386 HDassert(!hdr->cache_info.free_file_space_on_destroy || H5F_addr_defined(hdr->cache_info.addr));
387
388 /* Check for freeing file space for B-tree header */
389 if(hdr->cache_info.free_file_space_on_destroy) {
390 /* Release the space on disk */
391 /* (XXX: Nasty usage of internal DXPL value! -QAK) */
392 if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, hdr->cache_info.addr, (hsize_t)hdr->hdr_size) < 0)
393 HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree header")
394 } /* end if */
395
396 /* Release B-tree header info */
397 if(H5B2_hdr_free(hdr) < 0)
398 HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree header info")
399
400 done:
401 FUNC_LEAVE_NOAPI(ret_value)
402 } /* end H5B2__cache_hdr_dest() */
403
404
405 /*-------------------------------------------------------------------------
406 * Function: H5B2__cache_hdr_clear
407 *
408 * Purpose: Mark a B-tree header in memory as non-dirty.
409 *
410 * Return: Non-negative on success/Negative on failure
411 *
412 * Programmer: Quincey Koziol
413 * koziol@ncsa.uiuc.edu
414 * Feb 1 2005
415 *
416 *-------------------------------------------------------------------------
417 */
418 static herr_t
H5B2__cache_hdr_clear(H5F_t * f,H5B2_hdr_t * hdr,hbool_t destroy)419 H5B2__cache_hdr_clear(H5F_t *f, H5B2_hdr_t *hdr, hbool_t destroy)
420 {
421 herr_t ret_value = SUCCEED; /* Return value */
422
423 FUNC_ENTER_STATIC
424
425 /*
426 * Check arguments.
427 */
428 HDassert(hdr);
429
430 /* Reset the dirty flag. */
431 hdr->cache_info.is_dirty = FALSE;
432
433 if(destroy)
434 if(H5B2__cache_hdr_dest(f, hdr) < 0)
435 HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header")
436
437 done:
438 FUNC_LEAVE_NOAPI(ret_value)
439 } /* end H5B2__cache_hdr_clear() */
440
441
442 /*-------------------------------------------------------------------------
443 * Function: H5B2__cache_hdr_size
444 *
445 * Purpose: Compute the size in bytes of a B-tree header
446 * on disk, and return it in *size_ptr. On failure,
447 * the value of *size_ptr is undefined.
448 *
449 * Return: SUCCEED (Can't fail)
450 *
451 * Programmer: Quincey Koziol
452 * koziol@hdfgroup.org
453 * Feb 1 2005
454 *
455 *-------------------------------------------------------------------------
456 */
457 static herr_t
H5B2__cache_hdr_size(const H5F_t H5_ATTR_UNUSED * f,const H5B2_hdr_t * hdr,size_t * size_ptr)458 H5B2__cache_hdr_size(const H5F_t H5_ATTR_UNUSED *f, const H5B2_hdr_t *hdr, size_t *size_ptr)
459 {
460 FUNC_ENTER_STATIC_NOERR
461
462 /* check arguments */
463 HDassert(f);
464 HDassert(hdr);
465 HDassert(size_ptr);
466
467 /* Set size value */
468 *size_ptr = hdr->hdr_size;
469
470 FUNC_LEAVE_NOAPI(SUCCEED)
471 } /* H5B2__cache_hdr_size() */
472
473
474 /*-------------------------------------------------------------------------
475 * Function: H5B2__cache_internal_load
476 *
477 * Purpose: Loads a B-tree internal node from the disk.
478 *
479 * Return: Success: Pointer to a new B-tree internal node.
480 * Failure: NULL
481 *
482 * Programmer: Quincey Koziol
483 * koziol@ncsa.uiuc.edu
484 * Feb 2 2005
485 *
486 *-------------------------------------------------------------------------
487 */
488 static H5B2_internal_t *
H5B2__cache_internal_load(H5F_t * f,hid_t dxpl_id,haddr_t addr,void * _udata)489 H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
490 {
491 H5B2_internal_cache_ud_t *udata = (H5B2_internal_cache_ud_t *)_udata; /* Pointer to user data */
492 H5B2_internal_t *internal = NULL; /* Internal node read */
493 const uint8_t *p; /* Pointer into raw data buffer */
494 uint8_t *native; /* Pointer to native record info */
495 H5B2_node_ptr_t *int_node_ptr; /* Pointer to node pointer info */
496 uint32_t stored_chksum; /* Stored metadata checksum value */
497 uint32_t computed_chksum; /* Computed metadata checksum value */
498 unsigned u; /* Local index variable */
499 H5B2_internal_t *ret_value; /* Return value */
500
501 FUNC_ENTER_STATIC
502
503 /* Check arguments */
504 HDassert(f);
505 HDassert(H5F_addr_defined(addr));
506 HDassert(udata);
507
508 /* Allocate new internal node and reset cache info */
509 if(NULL == (internal = H5FL_MALLOC(H5B2_internal_t)))
510 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
511 HDmemset(&internal->cache_info, 0, sizeof(H5AC_info_t));
512
513 /* Set the B-tree header's file context for this operation */
514 udata->hdr->f = f;
515
516 /* Increment ref. count on B-tree header */
517 if(H5B2_hdr_incr(udata->hdr) < 0)
518 HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment ref. count on B-tree header")
519
520 /* Share B-tree information */
521 internal->hdr = udata->hdr;
522
523 /* Read header from disk */
524 if(H5F_block_read(f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, dxpl_id, udata->hdr->page) < 0)
525 HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree internal node")
526
527 p = udata->hdr->page;
528
529 /* Magic number */
530 if(HDmemcmp(p, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC))
531 HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "wrong B-tree internal node signature")
532 p += H5_SIZEOF_MAGIC;
533
534 /* Version */
535 if(*p++ != H5B2_INT_VERSION)
536 HGOTO_ERROR(H5E_BTREE, H5E_BADRANGE, NULL, "wrong B-tree internal node version")
537
538 /* B-tree type */
539 if(*p++ != (uint8_t)udata->hdr->cls->id)
540 HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "incorrect B-tree type")
541
542 /* Allocate space for the native keys in memory */
543 if(NULL == (internal->int_native = (uint8_t *)H5FL_FAC_MALLOC(udata->hdr->node_info[udata->depth].nat_rec_fac)))
544 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree internal native keys")
545
546 /* Allocate space for the node pointers in memory */
547 if(NULL == (internal->node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(udata->hdr->node_info[udata->depth].node_ptr_fac)))
548 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree internal node pointers")
549
550 /* Set the number of records in the leaf & it's depth */
551 internal->nrec = udata->nrec;
552 internal->depth = udata->depth;
553
554 /* Deserialize records for internal node */
555 native = internal->int_native;
556 for(u = 0; u < internal->nrec; u++) {
557 /* Decode record */
558 if((udata->hdr->cls->decode)(p, native, udata->hdr->cb_ctx) < 0)
559 HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, NULL, "unable to decode B-tree record")
560
561 /* Move to next record */
562 p += udata->hdr->rrec_size;
563 native += udata->hdr->cls->nrec_size;
564 } /* end for */
565
566 /* Deserialize node pointers for internal node */
567 int_node_ptr = internal->node_ptrs;
568 for(u = 0; u < (unsigned)(internal->nrec + 1); u++) {
569 /* Decode node pointer */
570 H5F_addr_decode(udata->f, (const uint8_t **)&p, &(int_node_ptr->addr));
571 UINT64DECODE_VAR(p, int_node_ptr->node_nrec, udata->hdr->max_nrec_size);
572 if(udata->depth > 1)
573 UINT64DECODE_VAR(p, int_node_ptr->all_nrec, udata->hdr->node_info[udata->depth - 1].cum_max_nrec_size)
574 else
575 int_node_ptr->all_nrec = int_node_ptr->node_nrec;
576
577 /* Move to next node pointer */
578 int_node_ptr++;
579 } /* end for */
580
581 /* Compute checksum on internal node */
582 computed_chksum = H5_checksum_metadata(udata->hdr->page, (size_t)(p - (const uint8_t *)udata->hdr->page), 0);
583
584 /* Metadata checksum */
585 UINT32DECODE(p, stored_chksum);
586
587 /* Sanity check parsing */
588 HDassert((size_t)(p - (const uint8_t *)udata->hdr->page) <= udata->hdr->node_size);
589
590 /* Verify checksum */
591 if(stored_chksum != computed_chksum)
592 HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 internal node")
593
594 /* Set return value */
595 ret_value = internal;
596
597 done:
598 if(!ret_value && internal)
599 if(H5B2_internal_free(internal) < 0)
600 HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, NULL, "unable to destroy B-tree internal node")
601
602 FUNC_LEAVE_NOAPI(ret_value)
603 } /* H5B2__cache_internal_load() */ /*lint !e818 Can't make udata a pointer to const */
604
605
606 /*-------------------------------------------------------------------------
607 * Function: H5B2__cache_internal_flush
608 *
609 * Purpose: Flushes a dirty B-tree internal node to disk.
610 *
611 * Return: Non-negative on success/Negative on failure
612 *
613 * Programmer: Quincey Koziol
614 * koziol@ncsa.uiuc.edu
615 * Feb 3 2005
616 *
617 *-------------------------------------------------------------------------
618 */
619 static herr_t
H5B2__cache_internal_flush(H5F_t * f,hid_t dxpl_id,hbool_t destroy,haddr_t addr,H5B2_internal_t * internal,unsigned H5_ATTR_UNUSED * flags_ptr)620 H5B2__cache_internal_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_internal_t *internal, unsigned H5_ATTR_UNUSED * flags_ptr)
621 {
622 herr_t ret_value = SUCCEED; /* Return value */
623
624 FUNC_ENTER_STATIC
625
626 /* check arguments */
627 HDassert(f);
628 HDassert(H5F_addr_defined(addr));
629 HDassert(internal);
630 HDassert(internal->hdr);
631
632 if(internal->cache_info.is_dirty) {
633 uint8_t *p; /* Pointer into raw data buffer */
634 uint8_t *native; /* Pointer to native record info */
635 H5B2_node_ptr_t *int_node_ptr; /* Pointer to node pointer info */
636 uint32_t metadata_chksum; /* Computed metadata checksum value */
637 unsigned u; /* Local index variable */
638
639 /* Set the B-tree header's file context for this operation */
640 internal->hdr->f = f;
641
642 p = internal->hdr->page;
643
644 /* Magic number */
645 HDmemcpy(p, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC);
646 p += H5_SIZEOF_MAGIC;
647
648 /* Version # */
649 *p++ = H5B2_INT_VERSION;
650
651 /* B-tree type */
652 *p++ = internal->hdr->cls->id;
653 HDassert((size_t)(p - internal->hdr->page) == (H5B2_INT_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM));
654
655 /* Serialize records for internal node */
656 native = internal->int_native;
657 for(u = 0; u < internal->nrec; u++) {
658 /* Encode record */
659 if((internal->hdr->cls->encode)(p, native, internal->hdr->cb_ctx) < 0)
660 HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree record")
661
662 /* Move to next record */
663 p += internal->hdr->rrec_size;
664 native += internal->hdr->cls->nrec_size;
665 } /* end for */
666
667 /* Serialize node pointers for internal node */
668 int_node_ptr = internal->node_ptrs;
669 for(u = 0; u < (unsigned)(internal->nrec + 1); u++) {
670 /* Encode node pointer */
671 H5F_addr_encode(f, &p, int_node_ptr->addr);
672 UINT64ENCODE_VAR(p, int_node_ptr->node_nrec, internal->hdr->max_nrec_size);
673 if(internal->depth > 1)
674 UINT64ENCODE_VAR(p, int_node_ptr->all_nrec, internal->hdr->node_info[internal->depth - 1].cum_max_nrec_size);
675
676 /* Move to next node pointer */
677 int_node_ptr++;
678 } /* end for */
679
680 /* Compute metadata checksum */
681 metadata_chksum = H5_checksum_metadata(internal->hdr->page, (size_t)(p - internal->hdr->page), 0);
682
683 /* Metadata checksum */
684 UINT32ENCODE(p, metadata_chksum);
685
686 /* Write the B-tree internal node */
687 HDassert((size_t)(p - internal->hdr->page) <= internal->hdr->node_size);
688 if(H5F_block_write(f, H5FD_MEM_BTREE, addr, internal->hdr->node_size, dxpl_id, internal->hdr->page) < 0)
689 HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree internal node to disk")
690
691 internal->cache_info.is_dirty = FALSE;
692 } /* end if */
693
694 if(destroy)
695 if(H5B2__cache_internal_dest(f, internal) < 0)
696 HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree internal node")
697
698 done:
699 FUNC_LEAVE_NOAPI(ret_value)
700 } /* H5B2__cache_internal_flush() */
701
702
703 /*-------------------------------------------------------------------------
704 * Function: H5B2__cache_internal_dest
705 *
706 * Purpose: Destroys a B-tree internal node in memory.
707 *
708 * Return: Non-negative on success/Negative on failure
709 *
710 * Programmer: Quincey Koziol
711 * koziol@ncsa.uiuc.edu
712 * Feb 2 2005
713 *
714 *-------------------------------------------------------------------------
715 */
716 static herr_t
H5B2__cache_internal_dest(H5F_t * f,H5B2_internal_t * internal)717 H5B2__cache_internal_dest(H5F_t *f, H5B2_internal_t *internal)
718 {
719 herr_t ret_value = SUCCEED; /* Return value */
720
721 FUNC_ENTER_STATIC
722
723 /* Check arguments */
724 HDassert(f);
725 HDassert(internal);
726 HDassert(internal->hdr);
727
728 /* If we're going to free the space on disk, the address must be valid */
729 HDassert(!internal->cache_info.free_file_space_on_destroy || H5F_addr_defined(internal->cache_info.addr));
730
731 /* Check for freeing file space for B-tree internal node */
732 if(internal->cache_info.free_file_space_on_destroy) {
733 /* Release the space on disk */
734 /* (XXX: Nasty usage of internal DXPL value! -QAK) */
735 if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, internal->cache_info.addr, (hsize_t)internal->hdr->node_size) < 0)
736 HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree internal node")
737 } /* end if */
738
739 /* Release v2 b-tree internal node */
740 if(H5B2_internal_free(internal) < 0)
741 HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to release v2 B-tree internal node")
742
743 done:
744 FUNC_LEAVE_NOAPI(ret_value)
745 } /* end H5B2__cache_internal_dest() */
746
747
748 /*-------------------------------------------------------------------------
749 * Function: H5B2__cache_internal_clear
750 *
751 * Purpose: Mark a B-tree internal node in memory as non-dirty.
752 *
753 * Return: Non-negative on success/Negative on failure
754 *
755 * Programmer: Quincey Koziol
756 * koziol@ncsa.uiuc.edu
757 * Feb 2 2005
758 *
759 *-------------------------------------------------------------------------
760 */
761 static herr_t
H5B2__cache_internal_clear(H5F_t * f,H5B2_internal_t * internal,hbool_t destroy)762 H5B2__cache_internal_clear(H5F_t *f, H5B2_internal_t *internal, hbool_t destroy)
763 {
764 herr_t ret_value = SUCCEED;
765
766 FUNC_ENTER_STATIC
767
768 /*
769 * Check arguments.
770 */
771 HDassert(internal);
772
773 /* Reset the dirty flag. */
774 internal->cache_info.is_dirty = FALSE;
775
776 if(destroy)
777 if(H5B2__cache_internal_dest(f, internal) < 0)
778 HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree internal node")
779
780 done:
781 FUNC_LEAVE_NOAPI(ret_value)
782 } /* end H5B2__cache_internal_clear() */
783
784
785 /*-------------------------------------------------------------------------
786 * Function: H5B2__cache_internal_size
787 *
788 * Purpose: Compute the size in bytes of a B-tree internal node
789 * on disk, and return it in *size_ptr. On failure,
790 * the value of *size_ptr is undefined.
791 *
792 * Return: Non-negative on success/Negative on failure
793 *
794 * Programmer: Quincey Koziol
795 * koziol@ncsa.uiuc.edu
796 * Feb 2 2005
797 *
798 *-------------------------------------------------------------------------
799 */
800 static herr_t
H5B2__cache_internal_size(const H5F_t H5_ATTR_UNUSED * f,const H5B2_internal_t * internal,size_t * size_ptr)801 H5B2__cache_internal_size(const H5F_t H5_ATTR_UNUSED *f, const H5B2_internal_t *internal, size_t *size_ptr)
802 {
803 FUNC_ENTER_STATIC_NOERR
804
805 /* check arguments */
806 HDassert(internal);
807 HDassert(internal->hdr);
808 HDassert(size_ptr);
809
810 /* Set size value */
811 *size_ptr = internal->hdr->node_size;
812
813 FUNC_LEAVE_NOAPI(SUCCEED)
814 } /* H5B2__cache_internal_size() */
815
816
817 /*-------------------------------------------------------------------------
818 * Function: H5B2__cache_leaf_load
819 *
820 * Purpose: Loads a B-tree leaf from the disk.
821 *
822 * Return: Success: Pointer to a new B-tree leaf node.
823 * Failure: NULL
824 *
825 * Programmer: Quincey Koziol
826 * koziol@ncsa.uiuc.edu
827 * Feb 2 2005
828 *
829 *-------------------------------------------------------------------------
830 */
831 static H5B2_leaf_t *
H5B2__cache_leaf_load(H5F_t H5_ATTR_UNUSED * f,hid_t dxpl_id,haddr_t addr,void * _udata)832 H5B2__cache_leaf_load(H5F_t H5_ATTR_UNUSED *f, hid_t dxpl_id, haddr_t addr, void *_udata)
833 {
834 H5B2_leaf_cache_ud_t *udata = (H5B2_leaf_cache_ud_t *)_udata;
835 H5B2_leaf_t *leaf = NULL; /* Pointer to lead node loaded */
836 const uint8_t *p; /* Pointer into raw data buffer */
837 uint8_t *native; /* Pointer to native keys */
838 uint32_t stored_chksum; /* Stored metadata checksum value */
839 uint32_t computed_chksum; /* Computed metadata checksum value */
840 unsigned u; /* Local index variable */
841 H5B2_leaf_t *ret_value; /* Return value */
842
843 FUNC_ENTER_STATIC
844
845 /* Check arguments */
846 HDassert(f);
847 HDassert(H5F_addr_defined(addr));
848 HDassert(udata);
849
850 /* Allocate new leaf node and reset cache info */
851 if(NULL == (leaf = H5FL_MALLOC(H5B2_leaf_t)))
852 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
853 HDmemset(&leaf->cache_info, 0, sizeof(H5AC_info_t));
854
855 /* Set the B-tree header's file context for this operation */
856 udata->hdr->f = udata->f;
857
858 /* Increment ref. count on B-tree header */
859 if(H5B2_hdr_incr(udata->hdr) < 0)
860 HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment ref. count on B-tree header")
861
862 /* Share B-tree header information */
863 leaf->hdr = udata->hdr;
864
865 /* Read header from disk */
866 if(H5F_block_read(udata->f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, dxpl_id, udata->hdr->page) < 0)
867 HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree leaf node")
868
869 p = udata->hdr->page;
870
871 /* Magic number */
872 if(HDmemcmp(p, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC))
873 HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree leaf node signature")
874 p += H5_SIZEOF_MAGIC;
875
876 /* Version */
877 if(*p++ != H5B2_LEAF_VERSION)
878 HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree leaf node version")
879
880 /* B-tree type */
881 if(*p++ != (uint8_t)udata->hdr->cls->id)
882 HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "incorrect B-tree type")
883
884 /* Allocate space for the native keys in memory */
885 if(NULL == (leaf->leaf_native = (uint8_t *)H5FL_FAC_MALLOC(udata->hdr->node_info[0].nat_rec_fac)))
886 HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree leaf native keys")
887
888 /* Set the number of records in the leaf */
889 leaf->nrec = udata->nrec;
890
891 /* Deserialize records for leaf node */
892 native = leaf->leaf_native;
893 for(u = 0; u < leaf->nrec; u++) {
894 /* Decode record */
895 if((udata->hdr->cls->decode)(p, native, udata->hdr->cb_ctx) < 0)
896 HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, NULL, "unable to decode B-tree record")
897
898 /* Move to next record */
899 p += udata->hdr->rrec_size;
900 native += udata->hdr->cls->nrec_size;
901 } /* end for */
902
903 /* Compute checksum on internal node */
904 computed_chksum = H5_checksum_metadata(udata->hdr->page, (size_t)(p - (const uint8_t *)udata->hdr->page), 0);
905
906 /* Metadata checksum */
907 UINT32DECODE(p, stored_chksum);
908
909 /* Sanity check parsing */
910 HDassert((size_t)(p - (const uint8_t *)udata->hdr->page) <= udata->hdr->node_size);
911
912 /* Verify checksum */
913 if(stored_chksum != computed_chksum)
914 HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 leaf node")
915
916 /* Set return value */
917 ret_value = leaf;
918
919 done:
920 if(!ret_value && leaf)
921 if(H5B2_leaf_free(leaf) < 0)
922 HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, NULL, "unable to destroy B-tree leaf node")
923
924 FUNC_LEAVE_NOAPI(ret_value)
925 } /* H5B2__cache_leaf_load() */ /*lint !e818 Can't make udata a pointer to const */
926
927
928 /*-------------------------------------------------------------------------
929 * Function: H5B2__cache_leaf_flush
930 *
931 * Purpose: Flushes a dirty B-tree leaf node to disk.
932 *
933 * Return: Non-negative on success/Negative on failure
934 *
935 * Programmer: Quincey Koziol
936 * koziol@ncsa.uiuc.edu
937 * Feb 2 2005
938 *
939 *-------------------------------------------------------------------------
940 */
941 static herr_t
H5B2__cache_leaf_flush(H5F_t * f,hid_t dxpl_id,hbool_t destroy,haddr_t addr,H5B2_leaf_t * leaf,unsigned H5_ATTR_UNUSED * flags_ptr)942 H5B2__cache_leaf_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_leaf_t *leaf, unsigned H5_ATTR_UNUSED * flags_ptr)
943 {
944 herr_t ret_value = SUCCEED; /* Return value */
945
946 FUNC_ENTER_STATIC
947
948 /* check arguments */
949 HDassert(f);
950 HDassert(H5F_addr_defined(addr));
951 HDassert(leaf);
952 HDassert(leaf->hdr);
953
954 if(leaf->cache_info.is_dirty) {
955 uint8_t *p; /* Pointer into raw data buffer */
956 uint8_t *native; /* Pointer to native keys */
957 uint32_t metadata_chksum; /* Computed metadata checksum value */
958 unsigned u; /* Local index variable */
959
960 /* Set the B-tree header's file context for this operation */
961 leaf->hdr->f = f;
962
963 p = leaf->hdr->page;
964
965 /* magic number */
966 HDmemcpy(p, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC);
967 p += H5_SIZEOF_MAGIC;
968
969 /* version # */
970 *p++ = H5B2_LEAF_VERSION;
971
972 /* b-tree type */
973 *p++ = leaf->hdr->cls->id;
974 HDassert((size_t)(p - leaf->hdr->page) == (H5B2_LEAF_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM));
975
976 /* Serialize records for leaf node */
977 native = leaf->leaf_native;
978 for(u = 0; u < leaf->nrec; u++) {
979 /* Encode record */
980 if((leaf->hdr->cls->encode)(p, native, leaf->hdr->cb_ctx) < 0)
981 HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree record")
982
983 /* Move to next record */
984 p += leaf->hdr->rrec_size;
985 native += leaf->hdr->cls->nrec_size;
986 } /* end for */
987
988 /* Compute metadata checksum */
989 metadata_chksum = H5_checksum_metadata(leaf->hdr->page, (size_t)(p - leaf->hdr->page), 0);
990
991 /* Metadata checksum */
992 UINT32ENCODE(p, metadata_chksum);
993
994 /* Write the B-tree leaf node */
995 HDassert((size_t)(p - leaf->hdr->page) <= leaf->hdr->node_size);
996 if(H5F_block_write(f, H5FD_MEM_BTREE, addr, leaf->hdr->node_size, dxpl_id, leaf->hdr->page) < 0)
997 HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree leaf node to disk")
998
999 leaf->cache_info.is_dirty = FALSE;
1000 } /* end if */
1001
1002 if(destroy)
1003 if(H5B2__cache_leaf_dest(f, leaf) < 0)
1004 HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree leaf node")
1005
1006 done:
1007 FUNC_LEAVE_NOAPI(ret_value)
1008 } /* H5B2__cache_leaf_flush() */
1009
1010
1011 /*-------------------------------------------------------------------------
1012 * Function: H5B2__cache_leaf_dest
1013 *
1014 * Purpose: Destroys a B-tree leaf node in memory.
1015 *
1016 * Return: Non-negative on success/Negative on failure
1017 *
1018 * Programmer: Quincey Koziol
1019 * koziol@ncsa.uiuc.edu
1020 * Feb 2 2005
1021 *
1022 *-------------------------------------------------------------------------
1023 */
1024 static herr_t
H5B2__cache_leaf_dest(H5F_t * f,H5B2_leaf_t * leaf)1025 H5B2__cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf)
1026 {
1027 herr_t ret_value = SUCCEED; /* Return value */
1028
1029 FUNC_ENTER_STATIC
1030
1031 /* Check arguments */
1032 HDassert(f);
1033 HDassert(leaf);
1034 HDassert(leaf->hdr);
1035
1036 /* If we're going to free the space on disk, the address must be valid */
1037 HDassert(!leaf->cache_info.free_file_space_on_destroy || H5F_addr_defined(leaf->cache_info.addr));
1038
1039 /* Check for freeing file space for B-tree leaf node */
1040 if(leaf->cache_info.free_file_space_on_destroy) {
1041 /* Release the space on disk */
1042 /* (XXX: Nasty usage of internal DXPL value! -QAK) */
1043 if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, leaf->cache_info.addr, (hsize_t)leaf->hdr->node_size) < 0)
1044 HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree leaf node")
1045 } /* end if */
1046
1047 /* Destroy v2 b-tree leaf node */
1048 if(H5B2_leaf_free(leaf) < 0)
1049 HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree leaf node")
1050
1051 done:
1052 FUNC_LEAVE_NOAPI(ret_value)
1053 } /* end H5B2__cache_leaf_dest() */
1054
1055
1056 /*-------------------------------------------------------------------------
1057 * Function: H5B2__cache_leaf_clear
1058 *
1059 * Purpose: Mark a B-tree leaf node in memory as non-dirty.
1060 *
1061 * Return: Non-negative on success/Negative on failure
1062 *
1063 * Programmer: Quincey Koziol
1064 * koziol@ncsa.uiuc.edu
1065 * Feb 2 2005
1066 *
1067 *-------------------------------------------------------------------------
1068 */
1069 static herr_t
H5B2__cache_leaf_clear(H5F_t * f,H5B2_leaf_t * leaf,hbool_t destroy)1070 H5B2__cache_leaf_clear(H5F_t *f, H5B2_leaf_t *leaf, hbool_t destroy)
1071 {
1072 herr_t ret_value = SUCCEED;
1073
1074 FUNC_ENTER_STATIC
1075
1076 /*
1077 * Check arguments.
1078 */
1079 HDassert(leaf);
1080
1081 /* Reset the dirty flag. */
1082 leaf->cache_info.is_dirty = FALSE;
1083
1084 if(destroy)
1085 if(H5B2__cache_leaf_dest(f, leaf) < 0)
1086 HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree leaf node")
1087
1088 done:
1089 FUNC_LEAVE_NOAPI(ret_value)
1090 } /* end H5B2__cache_leaf_clear() */
1091
1092
1093 /*-------------------------------------------------------------------------
1094 * Function: H5B2__cache_leaf_size
1095 *
1096 * Purpose: Compute the size in bytes of a B-tree leaf node
1097 * on disk, and return it in *size_ptr. On failure,
1098 * the value of *size_ptr is undefined.
1099 *
1100 * Return: Non-negative on success/Negative on failure
1101 *
1102 * Programmer: Quincey Koziol
1103 * koziol@ncsa.uiuc.edu
1104 * Feb 2 2005
1105 *
1106 *-------------------------------------------------------------------------
1107 */
1108 static herr_t
H5B2__cache_leaf_size(const H5F_t H5_ATTR_UNUSED * f,const H5B2_leaf_t * leaf,size_t * size_ptr)1109 H5B2__cache_leaf_size(const H5F_t H5_ATTR_UNUSED *f, const H5B2_leaf_t *leaf, size_t *size_ptr)
1110 {
1111 FUNC_ENTER_STATIC_NOERR
1112
1113 /* check arguments */
1114 HDassert(leaf);
1115 HDassert(leaf->hdr);
1116 HDassert(size_ptr);
1117
1118 /* Set size value */
1119 *size_ptr = leaf->hdr->node_size;
1120
1121 FUNC_LEAVE_NOAPI(SUCCEED)
1122 } /* H5B2__cache_leaf_size() */
1123
1124