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  * Programmer:	Quincey Koziol <koziol@ncsa.uiuc.edu>
16  *		Monday, January 31, 2005
17  *
18  * Purpose:	This file contains declarations which are visible only within
19  *		the H5B2 package.  Source files outside the H5B2 package should
20  *		include H5B2private.h instead.
21  */
22 #if !(defined H5B2_FRIEND || defined H5B2_MODULE)
23 #error "Do not include this file outside the H5B2 package!"
24 #endif
25 
26 #ifndef _H5B2pkg_H
27 #define _H5B2pkg_H
28 
29 /* Get package's private header */
30 #include "H5B2private.h"
31 
32 /* Other private headers needed by this file */
33 #include "H5ACprivate.h"	/* Metadata cache			*/
34 #include "H5FLprivate.h"	/* Free Lists                           */
35 
36 
37 /**************************/
38 /* Package Private Macros */
39 /**************************/
40 
41 /* Size of storage for number of records per node (on disk) */
42 #define H5B2_SIZEOF_RECORDS_PER_NODE    (unsigned)2
43 
44 /* Size of a "tree pointer" (on disk) */
45 /* (essentially, the largest internal pointer allowed) */
46 #define H5B2_TREE_POINTER_SIZE(sizeof_addr, sizeof_size)       (              \
47     (sizeof_addr) +                                                           \
48     H5B2_SIZEOF_RECORDS_PER_NODE +                                            \
49     (sizeof_size)                                                             \
50     )
51 
52 /* Size of a internal node pointer (on disk) */
53 #define H5B2_INT_POINTER_SIZE(h, d) (                                         \
54     (unsigned)(h)->sizeof_addr  /* Address of child node */                   \
55     + (h)->max_nrec_size        /* # of records in child node */              \
56     + (h)->node_info[(d) - 1].cum_max_nrec_size /* Total # of records in child & below */ \
57     )
58 
59 /* Size of checksum information (on disk) */
60 #define H5B2_SIZEOF_CHKSUM      4
61 
62 /* Format overhead for all v2 B-tree metadata in the file */
63 #define H5B2_METADATA_PREFIX_SIZE (                                           \
64     (unsigned)H5_SIZEOF_MAGIC   /* Signature */                               \
65     + (unsigned)1 /* Version */                                               \
66     + (unsigned)1 /* Tree type */                                             \
67     + (unsigned)H5B2_SIZEOF_CHKSUM /* Metadata checksum */                    \
68     )
69 
70 /* Size of the v2 B-tree header on disk */
71 #define H5B2_HEADER_SIZE(sizeof_addr, sizeof_size)   (                        \
72     /* General metadata fields */                                             \
73     H5B2_METADATA_PREFIX_SIZE                                                 \
74                                                                               \
75     /* Header specific fields */                                              \
76     + (unsigned)4 /* Node size, in bytes */                                   \
77     + (unsigned)2 /* Record size, in bytes */                                 \
78     + (unsigned)2 /* Depth of tree */                                         \
79     + (unsigned)1 /* Split % of full (as integer, ie. "98" means 98%) */      \
80     + (unsigned)1 /* Merge % of full (as integer, ie. "98" means 98%) */      \
81     + H5B2_TREE_POINTER_SIZE(sizeof_addr, sizeof_size)  /* Node pointer to root node in tree */ \
82     )
83 
84 /* Size of the v2 B-tree header on disk (via file pointer) */
85 #define H5B2_HEADER_SIZE_FILE(f)   (                                          \
86     H5B2_HEADER_SIZE(H5F_SIZEOF_ADDR(f), H5F_SIZEOF_SIZE(f))                  \
87     )
88 
89 /* Size of the v2 B-tree header on disk (via v2 B-tree header) */
90 #define H5B2_HEADER_SIZE_HDR(h)   (                                           \
91     H5B2_HEADER_SIZE((h)->sizeof_addr, (h)->sizeof_size)                      \
92     )
93 
94 /* Size of the v2 B-tree internal node prefix */
95 #define H5B2_INT_PREFIX_SIZE (                                                \
96     /* General metadata fields */                                             \
97     H5B2_METADATA_PREFIX_SIZE                                                 \
98                                                                               \
99     /* Header specific fields */                                              \
100     /* <none> */                                                              \
101     )
102 
103 /* Size of the v2 B-tree leaf node prefix */
104 #define H5B2_LEAF_PREFIX_SIZE (                                               \
105     /* General metadata fields */                                             \
106     H5B2_METADATA_PREFIX_SIZE                                                 \
107                                                                               \
108     /* Header specific fields */                                              \
109     /* <none> */                                                              \
110     )
111 
112 /* Macro to retrieve pointer to i'th native record for native record buffer */
113 #define H5B2_NAT_NREC(b, hdr, idx)  ((b) + (hdr)->nat_off[(idx)])
114 
115 /* Macro to retrieve pointer to i'th native record for internal node */
116 #define H5B2_INT_NREC(i, hdr, idx)  H5B2_NAT_NREC((i)->int_native, (hdr), (idx))
117 
118 /* Macro to retrieve pointer to i'th native record for leaf node */
119 #define H5B2_LEAF_NREC(l, hdr, idx)  H5B2_NAT_NREC((l)->leaf_native, (hdr), (idx))
120 
121 /* Number of records that fit into internal node */
122 /* (accounts for extra node pointer by counting it in with the prefix bytes) */
123 #define H5B2_NUM_INT_REC(h, d) \
124     (((h)->node_size - (H5B2_INT_PREFIX_SIZE + H5B2_INT_POINTER_SIZE(h, d))) / ((h)->rrec_size + H5B2_INT_POINTER_SIZE(h, d)))
125 
126 /* Uncomment this macro to enable extra sanity checking */
127 /* #define H5B2_DEBUG */
128 
129 
130 /****************************/
131 /* Package Private Typedefs */
132 /****************************/
133 
134 /* A "node pointer" to another B-tree node */
135 typedef struct {
136     haddr_t     addr;           /* Address of other node */
137     uint16_t    node_nrec;      /* Number of records used in node pointed to */
138     hsize_t     all_nrec;       /* Number of records in node pointed to and all it's children */
139 } H5B2_node_ptr_t;
140 
141 /* Information about a node at a given depth */
142 typedef struct {
143     unsigned    max_nrec;       /* Max. number of records in node */
144     unsigned    split_nrec;     /* Number of records to split node at */
145     unsigned    merge_nrec;     /* Number of records to merge node at */
146     hsize_t     cum_max_nrec;   /* Cumulative max. # of records below this node's depth */
147     uint8_t     cum_max_nrec_size; /* Size to store cumulative max. # of records for this node (in bytes) */
148     H5FL_fac_head_t *nat_rec_fac;   /* Factory for native record blocks */
149     H5FL_fac_head_t *node_ptr_fac;  /* Factory for node pointer blocks */
150 } H5B2_node_info_t;
151 
152 /* The B-tree header information */
153 typedef struct H5B2_hdr_t {
154     /* Information for H5AC cache functions, _must_ be first field in structure */
155     H5AC_info_t cache_info;
156 
157     /* Internal B-tree information (stored) */
158     H5B2_node_ptr_t root;       /* Node pointer to root node in B-tree        */
159 
160     /* Information set by user (stored) */
161     uint8_t     split_percent;  /* Percent full at which to split the node, when inserting */
162     uint8_t     merge_percent;  /* Percent full at which to merge the node, when deleting */
163     uint32_t    node_size;      /* Size of B-tree nodes, in bytes             */
164     uint32_t    rrec_size;      /* Size of "raw" (on disk) record, in bytes   */
165 
166     /* Dynamic information (stored) */
167     uint16_t	depth;		/* B-tree's overall depth                     */
168 
169     /* Derived information from user's information (not stored) */
170     uint8_t     max_nrec_size;  /* Size to store max. # of records in any node (in bytes) */
171 
172     /* Shared internal data structures (not stored) */
173     H5F_t       *f;             /* Pointer to the file that the B-tree is in */
174     haddr_t     addr;           /* Address of B-tree header in the file */
175     size_t      hdr_size;       /* Size of the B-tree header on disk */
176     size_t      rc;             /* Reference count of nodes using this header */
177     size_t      file_rc;        /* Reference count of files using this header */
178     hbool_t     pending_delete; /* B-tree is pending deletion */
179     uint8_t     sizeof_size;    /* Size of file sizes */
180     uint8_t     sizeof_addr;    /* Size of file addresses */
181     H5B2_remove_t remove_op;    /* Callback operator for deleting B-tree */
182     void        *remove_op_data;/* B-tree deletion callback's context */
183     uint8_t	*page;	        /* Common disk page for I/O */
184     size_t      *nat_off;       /* Array of offsets of native records */
185     H5B2_node_info_t *node_info; /* Table of node info structs for current depth of B-tree */
186     void        *min_native_rec; /* Pointer to minimum native record                  */
187     void        *max_native_rec; /* Pointer to maximum native record                  */
188 
189     /* SWMR / Flush dependency information (not stored) */
190     hbool_t     swmr_write;     /* Whether we are doing SWMR writes */
191     H5AC_proxy_entry_t *top_proxy;  /* 'Top' proxy cache entry for all B-tree entries */
192     void        *parent;        /* Pointer to 'top' proxy flush dependency
193                                  * parent, if it exists, otherwise NULL.
194                                  * If the v2 B-tree is being used to index a
195                                  * chunked dataset and the dataset metadata is
196                                  * modified by a SWMR writer, this field will
197                                  * be set equal to the object header proxy
198                                  * that is the flush dependency parent
199                                  * of the v2 B-tree header.
200  				 *
201  				 * The field is used to avoid duplicate setups
202                                  * of the flush dependency relationship, and to
203                                  * allow the v2 B-tree header to destroy the
204                                  * flush dependency on receipt of an eviction
205                                  * notification from the metadata cache.
206 				 */
207     uint64_t    shadow_epoch;   /* Epoch of header, for making shadow copies */
208 
209     /* Client information (not stored) */
210     const H5B2_class_t *cls;	/* Class of B-tree client */
211     void        *cb_ctx;        /* Client callback context */
212 } H5B2_hdr_t;
213 
214 /* B-tree leaf node information */
215 typedef struct H5B2_leaf_t {
216     /* Information for H5AC cache functions, _must_ be first field in structure */
217     H5AC_info_t cache_info;
218 
219     /* Internal B-tree information */
220     H5B2_hdr_t	*hdr;		/* Pointer to the [pinned] v2 B-tree header   */
221     uint8_t     *leaf_native;   /* Pointer to native records                  */
222     uint16_t    nrec;           /* Number of records in node                  */
223 
224     /* SWMR / Flush dependency information (not stored) */
225     H5AC_proxy_entry_t *top_proxy;  /* 'Top' proxy cache entry for all B-tree entries */
226     void        *parent;        /* Flush dependency parent for leaf           */
227     uint64_t    shadow_epoch;   /* Epoch of node, for making shadow copies */
228 } H5B2_leaf_t;
229 
230 /* B-tree internal node information */
231 typedef struct H5B2_internal_t {
232     /* Information for H5AC cache functions, _must_ be first field in structure */
233     H5AC_info_t cache_info;
234 
235     /* Internal B-tree information */
236     H5B2_hdr_t	*hdr;		/* Pointer to the [pinned] v2 B-tree header   */
237     uint8_t     *int_native;    /* Pointer to native records                  */
238     H5B2_node_ptr_t *node_ptrs; /* Pointer to node pointers                   */
239     uint16_t    nrec;           /* Number of records in node                  */
240     uint16_t    depth;          /* Depth of this node in the B-tree           */
241 
242     /* SWMR / Flush dependency information (not stored) */
243     H5AC_proxy_entry_t *top_proxy;  /* 'Top' proxy cache entry for all B-tree entries */
244     void        *parent;        /* Flush dependency parent for internal node  */
245     uint64_t    shadow_epoch;   /* Epoch of node, for making shadow copies */
246 } H5B2_internal_t;
247 
248 /* v2 B-tree */
249 struct H5B2_t {
250     H5B2_hdr_t  *hdr;           /* Pointer to internal v2 B-tree header info */
251     H5F_t      *f;              /* Pointer to file for v2 B-tree */
252 };
253 
254 /* Node position, for min/max determination */
255 typedef enum H5B2_nodepos_t {
256     H5B2_POS_ROOT,              /* Node is root (i.e. both right & left-most in tree) */
257     H5B2_POS_RIGHT,             /* Node is right-most in tree, at a given depth */
258     H5B2_POS_LEFT,              /* Node is left-most in tree, at a given depth */
259     H5B2_POS_MIDDLE             /* Node is neither right or left-most in tree */
260 } H5B2_nodepos_t;
261 
262 /* Update status */
263 typedef enum H5B2_update_status_t {
264     H5B2_UPDATE_UNKNOWN,            /* Unknown update status (initial state) */
265     H5B2_UPDATE_MODIFY_DONE,        /* Update successfully modified existing record */
266     H5B2_UPDATE_SHADOW_DONE,        /* Update modified existing record and modified node was shadowed */
267     H5B2_UPDATE_INSERT_DONE,        /* Update inserted record successfully */
268     H5B2_UPDATE_INSERT_CHILD_FULL   /* Update will insert record, but child is full */
269 } H5B2_update_status_t;
270 
271 /* Callback info for loading a v2 B-tree header into the cache */
272 typedef struct H5B2_hdr_cache_ud_t {
273     H5F_t *f;                   /* File that v2 b-tree header is within */
274     haddr_t addr;               /* Address of B-tree header in the file */
275     void *ctx_udata;            /* User-data for protecting */
276 } H5B2_hdr_cache_ud_t;
277 
278 /* Callback info for loading a v2 B-tree internal node into the cache */
279 typedef struct H5B2_internal_cache_ud_t {
280     H5F_t *f;                   /* File that v2 b-tree header is within */
281     H5B2_hdr_t *hdr;            /* v2 B-tree header */
282     void *parent;               /* Flush dependency parent */
283     uint16_t nrec;              /* Number of records in node to load */
284     uint16_t depth;             /* Depth of node to load */
285 } H5B2_internal_cache_ud_t;
286 
287 /* Callback info for loading a v2 B-tree leaf node into the cache */
288 typedef struct H5B2_leaf_cache_ud_t {
289     H5F_t *f;                   /* File that v2 b-tree header is within */
290     H5B2_hdr_t *hdr;            /* v2 B-tree header */
291     void *parent;               /* Flush dependency parent */
292     uint16_t nrec;              /* Number of records in node to load */
293 } H5B2_leaf_cache_ud_t;
294 
295 #ifdef H5B2_TESTING
296 /* Node information for testing */
297 typedef struct H5B2_node_info_test_t {
298     uint16_t depth;             /* Depth of node */
299     uint16_t nrec;              /* Number of records in node */
300 } H5B2_node_info_test_t;
301 #endif /* H5B2_TESTING */
302 
303 
304 /*****************************/
305 /* Package Private Variables */
306 /*****************************/
307 
308 /* Declare a free list to manage the H5B2_internal_t struct */
309 H5FL_EXTERN(H5B2_internal_t);
310 
311 /* Declare a free list to manage the H5B2_leaf_t struct */
312 H5FL_EXTERN(H5B2_leaf_t);
313 
314 /* Internal v2 B-tree testing class */
315 #ifdef H5B2_TESTING
316 H5_DLLVAR const H5B2_class_t H5B2_TEST[1];
317 H5_DLLVAR const H5B2_class_t H5B2_TEST2[1];
318 
319 /* B-tree record for testing H5B2_TEST2 class */
320 typedef struct H5B2_test_rec_t {
321     hsize_t key;        /* Key for record */
322     hsize_t val;        /* Value for record */
323 } H5B2_test_rec_t;
324 #endif /* H5B2_TESTING */
325 
326 /* Array of v2 B-tree client ID -> client class mappings */
327 extern const H5B2_class_t *const H5B2_client_class_g[H5B2_NUM_BTREE_ID];
328 
329 
330 /******************************/
331 /* Package Private Prototypes */
332 /******************************/
333 
334 /* Generic routines */
335 H5_DLL herr_t H5B2__create_flush_depend(H5AC_info_t *parent_entry,
336     H5AC_info_t *child_entry);
337 H5_DLL herr_t H5B2__update_flush_depend(H5B2_hdr_t *hdr, hid_t dxpl_id,
338     unsigned depth, const H5B2_node_ptr_t *node_ptr, void *old_parent,
339     void *new_parent);
340 H5_DLL herr_t H5B2__destroy_flush_depend(H5AC_info_t *parent_entry,
341     H5AC_info_t *child_entry);
342 
343 /* Internal node management routines */
344 H5_DLL herr_t H5B2__split1(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
345     H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr,
346     H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx);
347 H5_DLL herr_t H5B2__redistribute2(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
348     H5B2_internal_t *internal, unsigned idx);
349 H5_DLL herr_t H5B2__redistribute3(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
350     H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx);
351 H5_DLL herr_t H5B2__merge2(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
352     H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr,
353     H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx);
354 H5_DLL herr_t H5B2__merge3(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
355     H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr,
356     H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx);
357 
358 /* Routines for managing B-tree header info */
359 H5_DLL H5B2_hdr_t *H5B2__hdr_alloc(H5F_t *f);
360 H5_DLL haddr_t H5B2__hdr_create(H5F_t *f, hid_t dxpl_id,
361     const H5B2_create_t *cparam, void *ctx_udata);
362 H5_DLL herr_t H5B2__hdr_init(H5B2_hdr_t *hdr, const H5B2_create_t *cparam,
363     void *ctx_udata, uint16_t depth);
364 H5_DLL herr_t H5B2__hdr_incr(H5B2_hdr_t *hdr);
365 H5_DLL herr_t H5B2__hdr_decr(H5B2_hdr_t *hdr);
366 H5_DLL herr_t H5B2__hdr_fuse_incr(H5B2_hdr_t *hdr);
367 H5_DLL size_t H5B2__hdr_fuse_decr(H5B2_hdr_t *hdr);
368 H5_DLL herr_t H5B2__hdr_dirty(H5B2_hdr_t *hdr);
369 H5_DLL H5B2_hdr_t *H5B2__hdr_protect(H5F_t *f, hid_t dxpl_id, haddr_t hdr_addr,
370     void *ctx_udata, unsigned flags);
371 H5_DLL herr_t H5B2__hdr_unprotect(H5B2_hdr_t *hdr, hid_t dxpl_id,
372     unsigned cache_flags);
373 H5_DLL herr_t H5B2__hdr_delete(H5B2_hdr_t *hdr, hid_t dxpl_id);
374 
375 /* Routines for operating on leaf nodes */
376 H5_DLL H5B2_leaf_t * H5B2__protect_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
377     void *parent, H5B2_node_ptr_t *node_ptr, hbool_t shadow, unsigned flags);
378 H5_DLL herr_t H5B2__swap_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
379     H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx,
380     void *swap_loc);
381 
382 /* Routines for operating on internal nodes */
383 H5_DLL H5B2_internal_t *H5B2__protect_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
384     void *parent, H5B2_node_ptr_t *node_ptr, uint16_t depth, hbool_t shadow,
385     unsigned flags);
386 
387 /* Routines for allocating nodes */
388 H5_DLL herr_t H5B2__split_root(H5B2_hdr_t *hdr, hid_t dxpl_id);
389 H5_DLL herr_t H5B2__create_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, void *parent,
390     H5B2_node_ptr_t *node_ptr);
391 H5_DLL herr_t H5B2__create_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, void *parent,
392     H5B2_node_ptr_t *node_ptr, uint16_t depth);
393 
394 /* Routines for releasing structures */
395 H5_DLL herr_t H5B2__hdr_free(H5B2_hdr_t *hdr);
396 H5_DLL herr_t H5B2__leaf_free(H5B2_leaf_t *l);
397 H5_DLL herr_t H5B2__internal_free(H5B2_internal_t *i);
398 
399 /* Routines for inserting records */
400 H5_DLL herr_t H5B2__insert(H5B2_hdr_t *hdr, hid_t dxpl_id, void *udata);
401 H5_DLL herr_t H5B2__insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
402     uint16_t depth, unsigned *parent_cache_info_flags_ptr,
403     H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, void *parent, void *udata);
404 H5_DLL herr_t H5B2__insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
405     H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, void *parent, void *udata);
406 
407 /* Routines for update records */
408 H5_DLL herr_t H5B2__update_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
409     uint16_t depth, unsigned *parent_cache_info_flags_ptr,
410     H5B2_node_ptr_t *curr_node_ptr, H5B2_update_status_t *status,
411     H5B2_nodepos_t curr_pos, void *parent, void *udata, H5B2_modify_t op,
412     void *op_data);
413 H5_DLL herr_t H5B2__update_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
414     H5B2_node_ptr_t *curr_node_ptr, H5B2_update_status_t *status,
415     H5B2_nodepos_t curr_pos, void *parent, void *udata, H5B2_modify_t op,
416     void *op_data);
417 
418 /* Routines for iterating over nodes/records */
419 H5_DLL herr_t H5B2__iterate_node(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
420     const H5B2_node_ptr_t *curr_node, void *parent, H5B2_operator_t op, void *op_data);
421 H5_DLL herr_t H5B2__node_size(H5B2_hdr_t *hdr, hid_t dxpl_id,
422     uint16_t depth, const H5B2_node_ptr_t *curr_node, void *parent,
423     hsize_t *op_data);
424 
425 /* Routines for locating records */
426 H5_DLL herr_t H5B2__locate_record(const H5B2_class_t *type, unsigned nrec,
427     size_t *rec_off, const uint8_t *native, const void *udata, unsigned *idx, int *result);
428 H5_DLL herr_t H5B2__neighbor_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
429     uint16_t depth, H5B2_node_ptr_t *curr_node_ptr, void *neighbor_loc,
430     H5B2_compare_t comp, void *parent, void *udata, H5B2_found_t op,
431     void *op_data);
432 H5_DLL herr_t H5B2__neighbor_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
433     H5B2_node_ptr_t *curr_node_ptr, void *neighbor_loc, H5B2_compare_t comp,
434     void *parent, void *udata, H5B2_found_t op, void *op_data);
435 
436 /* Routines for removing records */
437 H5_DLL herr_t H5B2__remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
438     hbool_t *depth_decreased, void *swap_loc, void *swap_parent, uint16_t depth,
439     H5AC_info_t *parent_cache_info, unsigned *parent_cache_info_flags_ptr,
440     H5B2_nodepos_t curr_pos, H5B2_node_ptr_t *curr_node_ptr, void *udata,
441     H5B2_remove_t op, void *op_data);
442 H5_DLL herr_t H5B2__remove_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
443     H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, void *parent,
444     void *udata, H5B2_remove_t op, void *op_data);
445 H5_DLL herr_t H5B2__remove_internal_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
446     hbool_t *depth_decreased, void *swap_loc, void *swap_parent, uint16_t depth,
447     H5AC_info_t *parent_cache_info, unsigned *parent_cache_info_flags_ptr,
448     H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, hsize_t n,
449     H5B2_remove_t op, void *op_data);
450 H5_DLL herr_t H5B2__remove_leaf_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
451     H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, void *parent,
452     unsigned idx, H5B2_remove_t op, void *op_data);
453 
454 /* Routines for deleting nodes */
455 H5_DLL herr_t H5B2__delete_node(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
456     const H5B2_node_ptr_t *curr_node, void *parent, H5B2_remove_t op,
457     void *op_data);
458 
459 /* Debugging routines for dumping file structures */
460 H5_DLL herr_t H5B2__hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
461     FILE *stream, int indent, int fwidth, const H5B2_class_t *type, haddr_t obj_addr);
462 H5_DLL herr_t H5B2__int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
463     FILE *stream, int indent, int fwidth, const H5B2_class_t *type,
464     haddr_t hdr_addr, unsigned nrec, unsigned depth, haddr_t obj_addr);
465 H5_DLL herr_t H5B2__leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
466     FILE *stream, int indent, int fwidth, const H5B2_class_t *type,
467     haddr_t hdr_addr, unsigned nrec, haddr_t obj_addr);
468 
469 /* Sanity checking routines */
470 #ifdef H5B2_DEBUG
471 /* Don't label these with H5_ATTR_PURE or you'll get even more warnings... */
472 H5_DLL herr_t H5B2__assert_internal(hsize_t parent_all_nrec, const H5B2_hdr_t *hdr, const H5B2_internal_t *internal);
473 H5_DLL herr_t H5B2__assert_internal2(hsize_t parent_all_nrec, const H5B2_hdr_t *hdr, const H5B2_internal_t *internal, const H5B2_internal_t *internal2);
474 H5_DLL herr_t H5B2__assert_leaf(const H5B2_hdr_t *hdr, const H5B2_leaf_t *leaf);
475 H5_DLL herr_t H5B2__assert_leaf2(const H5B2_hdr_t *hdr, const H5B2_leaf_t *leaf, const H5B2_leaf_t *leaf2);
476 #endif /* H5B2_DEBUG */
477 
478 /* Testing routines */
479 #ifdef H5B2_TESTING
480 H5_DLL herr_t H5B2_get_root_addr_test(H5B2_t *bt2, haddr_t *root_addr);
481 H5_DLL int H5B2_get_node_depth_test(H5B2_t *bt2, hid_t dxpl_id, void *udata);
482 H5_DLL herr_t H5B2_get_node_info_test(H5B2_t *bt2, hid_t dxpl_id,
483     void *udata, H5B2_node_info_test_t *ninfo);
484 #endif /* H5B2_TESTING */
485 
486 #endif /* _H5B2pkg_H */
487 
488