Coverage Report

Created: 2025-08-28 06:37

/src/hdf5/src/H5HFbtree2.c
Line
Count
Source (jump to first uncovered line)
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the LICENSE file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*-------------------------------------------------------------------------
14
 *
15
 * Created:   H5HFbtree2.c
16
 *
17
 * Purpose:   v2 B-tree callbacks for "huge" object tracker
18
 *
19
 *-------------------------------------------------------------------------
20
 */
21
22
/****************/
23
/* Module Setup */
24
/****************/
25
26
#include "H5HFmodule.h" /* This source code file is part of the H5HF module */
27
28
/***********/
29
/* Headers */
30
/***********/
31
#include "H5private.h"   /* Generic Functions                        */
32
#include "H5B2private.h" /* B-Trees (Version 2)                      */
33
#include "H5Eprivate.h"  /* Error Handling                           */
34
#include "H5Fprivate.h"  /* Files                                    */
35
#include "H5FLprivate.h" /* Free Lists                               */
36
#include "H5HFpkg.h"     /* Fractal Heaps                            */
37
#include "H5MFprivate.h" /* File Memory Management                   */
38
39
/****************/
40
/* Local Macros */
41
/****************/
42
43
/******************/
44
/* Local Typedefs */
45
/******************/
46
47
/* v2 B-tree client callback context */
48
typedef struct H5HF_huge_bt2_ctx_t {
49
    uint8_t sizeof_size; /* Size of file sizes */
50
    uint8_t sizeof_addr; /* Size of file addresses */
51
} H5HF_huge_bt2_ctx_t;
52
53
/********************/
54
/* Package Typedefs */
55
/********************/
56
57
/********************/
58
/* Local Prototypes */
59
/********************/
60
61
/* v2 B-tree driver callbacks */
62
63
/* Common callbacks */
64
static void  *H5HF__huge_bt2_crt_context(void *udata);
65
static herr_t H5HF__huge_bt2_dst_context(void *ctx);
66
67
/* Callbacks for indirect objects */
68
static herr_t H5HF__huge_bt2_indir_store(void *native, const void *udata);
69
static herr_t H5HF__huge_bt2_indir_compare(const void *rec1, const void *rec2, int *result);
70
static herr_t H5HF__huge_bt2_indir_encode(uint8_t *raw, const void *native, void *ctx);
71
static herr_t H5HF__huge_bt2_indir_decode(const uint8_t *raw, void *native, void *ctx);
72
static herr_t H5HF__huge_bt2_indir_debug(FILE *stream, int indent, int fwidth, const void *record,
73
                                         const void *_udata);
74
75
/* Callbacks for filtered indirect objects */
76
static herr_t H5HF__huge_bt2_filt_indir_store(void *native, const void *udata);
77
static herr_t H5HF__huge_bt2_filt_indir_compare(const void *rec1, const void *rec2, int *result);
78
static herr_t H5HF__huge_bt2_filt_indir_encode(uint8_t *raw, const void *native, void *ctx);
79
static herr_t H5HF__huge_bt2_filt_indir_decode(const uint8_t *raw, void *native, void *ctx);
80
static herr_t H5HF__huge_bt2_filt_indir_debug(FILE *stream, int indent, int fwidth, const void *record,
81
                                              const void *_udata);
82
83
/* Callbacks for direct objects */
84
static herr_t H5HF__huge_bt2_dir_store(void *native, const void *udata);
85
static herr_t H5HF__huge_bt2_dir_compare(const void *rec1, const void *rec2, int *result);
86
static herr_t H5HF__huge_bt2_dir_encode(uint8_t *raw, const void *native, void *ctx);
87
static herr_t H5HF__huge_bt2_dir_decode(const uint8_t *raw, void *native, void *ctx);
88
static herr_t H5HF__huge_bt2_dir_debug(FILE *stream, int indent, int fwidth, const void *record,
89
                                       const void *_udata);
90
91
/* Callbacks for filtered direct objects */
92
static herr_t H5HF__huge_bt2_filt_dir_store(void *native, const void *udata);
93
static herr_t H5HF__huge_bt2_filt_dir_compare(const void *rec1, const void *rec2, int *result);
94
static herr_t H5HF__huge_bt2_filt_dir_encode(uint8_t *raw, const void *native, void *ctx);
95
static herr_t H5HF__huge_bt2_filt_dir_decode(const uint8_t *raw, void *native, void *ctx);
96
static herr_t H5HF__huge_bt2_filt_dir_debug(FILE *stream, int indent, int fwidth, const void *record,
97
                                            const void *_udata);
98
99
/*********************/
100
/* Package Variables */
101
/*********************/
102
/* v2 B-tree class for indirectly accessed 'huge' objects */
103
const H5B2_class_t H5HF_HUGE_BT2_INDIR[1] = {{
104
    /* B-tree class information */
105
    H5B2_FHEAP_HUGE_INDIR_ID,          /* Type of B-tree */
106
    "H5B2_FHEAP_HUGE_INDIR_ID",        /* Name of B-tree class */
107
    sizeof(H5HF_huge_bt2_indir_rec_t), /* Size of native record */
108
    H5HF__huge_bt2_crt_context,        /* Create client callback context */
109
    H5HF__huge_bt2_dst_context,        /* Destroy client callback context */
110
    H5HF__huge_bt2_indir_store,        /* Record storage callback */
111
    H5HF__huge_bt2_indir_compare,      /* Record comparison callback */
112
    H5HF__huge_bt2_indir_encode,       /* Record encoding callback */
113
    H5HF__huge_bt2_indir_decode,       /* Record decoding callback */
114
    H5HF__huge_bt2_indir_debug         /* Record debugging callback */
115
}};
116
117
/* v2 B-tree class for indirectly accessed, filtered 'huge' objects */
118
const H5B2_class_t H5HF_HUGE_BT2_FILT_INDIR[1] = {{
119
    /* B-tree class information */
120
    H5B2_FHEAP_HUGE_FILT_INDIR_ID,          /* Type of B-tree */
121
    "H5B2_FHEAP_HUGE_FILT_INDIR_ID",        /* Name of B-tree class */
122
    sizeof(H5HF_huge_bt2_filt_indir_rec_t), /* Size of native record */
123
    H5HF__huge_bt2_crt_context,             /* Create client callback context */
124
    H5HF__huge_bt2_dst_context,             /* Destroy client callback context */
125
    H5HF__huge_bt2_filt_indir_store,        /* Record storage callback */
126
    H5HF__huge_bt2_filt_indir_compare,      /* Record comparison callback */
127
    H5HF__huge_bt2_filt_indir_encode,       /* Record encoding callback */
128
    H5HF__huge_bt2_filt_indir_decode,       /* Record decoding callback */
129
    H5HF__huge_bt2_filt_indir_debug         /* Record debugging callback */
130
}};
131
132
/* v2 B-tree class for directly accessed 'huge' objects */
133
const H5B2_class_t H5HF_HUGE_BT2_DIR[1] = {{
134
    /* B-tree class information */
135
    H5B2_FHEAP_HUGE_DIR_ID,          /* Type of B-tree */
136
    "H5B2_FHEAP_HUGE_DIR_ID",        /* Name of B-tree class */
137
    sizeof(H5HF_huge_bt2_dir_rec_t), /* Size of native record */
138
    H5HF__huge_bt2_crt_context,      /* Create client callback context */
139
    H5HF__huge_bt2_dst_context,      /* Destroy client callback context */
140
    H5HF__huge_bt2_dir_store,        /* Record storage callback */
141
    H5HF__huge_bt2_dir_compare,      /* Record comparison callback */
142
    H5HF__huge_bt2_dir_encode,       /* Record encoding callback */
143
    H5HF__huge_bt2_dir_decode,       /* Record decoding callback */
144
    H5HF__huge_bt2_dir_debug         /* Record debugging callback */
145
}};
146
147
/* v2 B-tree class for directly accessed, filtered 'huge' objects */
148
const H5B2_class_t H5HF_HUGE_BT2_FILT_DIR[1] = {{
149
    /* B-tree class information */
150
    H5B2_FHEAP_HUGE_FILT_DIR_ID,          /* Type of B-tree */
151
    "H5B2_FHEAP_HUGE_FILT_DIR_ID",        /* Name of B-tree class */
152
    sizeof(H5HF_huge_bt2_filt_dir_rec_t), /* Size of native record */
153
    H5HF__huge_bt2_crt_context,           /* Create client callback context */
154
    H5HF__huge_bt2_dst_context,           /* Destroy client callback context */
155
    H5HF__huge_bt2_filt_dir_store,        /* Record storage callback */
156
    H5HF__huge_bt2_filt_dir_compare,      /* Record comparison callback */
157
    H5HF__huge_bt2_filt_dir_encode,       /* Record encoding callback */
158
    H5HF__huge_bt2_filt_dir_decode,       /* Record decoding callback */
159
    H5HF__huge_bt2_filt_dir_debug         /* Record debugging callback */
160
}};
161
162
/*****************************/
163
/* Library Private Variables */
164
/*****************************/
165
166
/*******************/
167
/* Local Variables */
168
/*******************/
169
170
/* Declare a free list to manage the H5HF_huge_bt2_ctx_t struct */
171
H5FL_DEFINE_STATIC(H5HF_huge_bt2_ctx_t);
172
173
/*-------------------------------------------------------------------------
174
 * Function:  H5HF__huge_bt2_crt_context
175
 *
176
 * Purpose: Create client callback context
177
 *
178
 * Note:  Common to all 'huge' v2 B-tree clients
179
 *
180
 * Return:  Success:  non-NULL
181
 *    Failure:  NULL
182
 *
183
 *-------------------------------------------------------------------------
184
 */
185
static void *
186
H5HF__huge_bt2_crt_context(void *_f)
187
0
{
188
0
    H5F_t               *f = (H5F_t *)_f;  /* User data for building callback context */
189
0
    H5HF_huge_bt2_ctx_t *ctx;              /* Callback context structure */
190
0
    void                *ret_value = NULL; /* Return value */
191
192
0
    FUNC_ENTER_PACKAGE
193
194
    /* Sanity check */
195
0
    assert(f);
196
197
    /* Allocate callback context */
198
0
    if (NULL == (ctx = H5FL_MALLOC(H5HF_huge_bt2_ctx_t)))
199
0
        HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate callback context");
200
201
    /* Determine the size of addresses & lengths in the file */
202
0
    ctx->sizeof_addr = H5F_SIZEOF_ADDR(f);
203
0
    ctx->sizeof_size = H5F_SIZEOF_SIZE(f);
204
205
    /* Set return value */
206
0
    ret_value = ctx;
207
208
0
done:
209
0
    FUNC_LEAVE_NOAPI(ret_value)
210
0
} /* H5HF__huge_bt2_crt_context() */
211
212
/*-------------------------------------------------------------------------
213
 * Function:  H5HF__huge_bt2_dst_context
214
 *
215
 * Purpose: Destroy client callback context
216
 *
217
 * Note:  Common to all 'huge' v2 B-tree clients
218
 *
219
 * Return:  Success:  non-negative
220
 *    Failure:  negative
221
 *
222
 *-------------------------------------------------------------------------
223
 */
224
static herr_t
225
H5HF__huge_bt2_dst_context(void *_ctx)
226
0
{
227
0
    H5HF_huge_bt2_ctx_t *ctx = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
228
229
0
    FUNC_ENTER_PACKAGE_NOERR
230
231
    /* Sanity check */
232
0
    assert(ctx);
233
234
    /* Release callback context */
235
0
    ctx = H5FL_FREE(H5HF_huge_bt2_ctx_t, ctx);
236
237
0
    FUNC_LEAVE_NOAPI(SUCCEED)
238
0
} /* H5HF__huge_bt2_dst_context() */
239
240
/*-------------------------------------------------------------------------
241
 * Function:  H5HF__huge_bt2_indir_found
242
 *
243
 * Purpose: Retrieve record for indirectly accessed 'huge' object, when
244
 *              it's found in the v2 B-tree
245
 *
246
 * Return:  Success:  non-negative
247
 *    Failure:  negative
248
 *
249
 *-------------------------------------------------------------------------
250
 */
251
herr_t
252
H5HF__huge_bt2_indir_found(const void *nrecord, void *op_data)
253
0
{
254
0
    FUNC_ENTER_PACKAGE_NOERR
255
256
0
    *(H5HF_huge_bt2_indir_rec_t *)op_data = *(const H5HF_huge_bt2_indir_rec_t *)nrecord;
257
258
0
    FUNC_LEAVE_NOAPI(SUCCEED)
259
0
} /* H5HF__huge_bt2_indir_found() */
260
261
/*-------------------------------------------------------------------------
262
 * Function:  H5HF__huge_bt2_indir_remove
263
 *
264
 * Purpose: Free space for indirectly accessed 'huge' object, as v2 B-tree
265
 *              is being deleted or v2 B-tree node is removed
266
 *
267
 * Return:  Success:  non-negative
268
 *    Failure:  negative
269
 *
270
 *-------------------------------------------------------------------------
271
 */
272
herr_t
273
H5HF__huge_bt2_indir_remove(const void *nrecord, void *_udata)
274
0
{
275
0
    H5HF_huge_remove_ud_t *udata     = (H5HF_huge_remove_ud_t *)_udata; /* User callback data */
276
0
    herr_t                 ret_value = SUCCEED;                         /* Return value */
277
278
0
    FUNC_ENTER_PACKAGE
279
280
    /* Free the space in the file for the object being removed */
281
0
    if (H5MF_xfree(udata->hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->addr,
282
0
                   ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->len) < 0)
283
0
        HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free space for huge object on disk");
284
285
    /* Set the length of the object removed */
286
0
    udata->obj_len = ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->len;
287
288
0
done:
289
0
    FUNC_LEAVE_NOAPI(ret_value)
290
0
} /* H5HF__huge_bt2_indir_remove() */
291
292
/*-------------------------------------------------------------------------
293
 * Function:  H5HF__huge_bt2_indir_store
294
 *
295
 * Purpose: Store native information into record for v2 B-tree
296
 *
297
 * Return:  Success:  non-negative
298
 *    Failure:  negative
299
 *
300
 *-------------------------------------------------------------------------
301
 */
302
static herr_t
303
H5HF__huge_bt2_indir_store(void *nrecord, const void *udata)
304
0
{
305
0
    FUNC_ENTER_PACKAGE_NOERR
306
307
0
    *(H5HF_huge_bt2_indir_rec_t *)nrecord = *(const H5HF_huge_bt2_indir_rec_t *)udata;
308
309
0
    FUNC_LEAVE_NOAPI(SUCCEED)
310
0
} /* H5HF__huge_bt2_indir_store() */
311
312
/*-------------------------------------------------------------------------
313
 * Function:  H5HF__huge_bt2_indir_compare
314
 *
315
 * Purpose: Compare two native information records, according to some key
316
 *
317
 * Return:  <0 if rec1 < rec2
318
 *              =0 if rec1 == rec2
319
 *              >0 if rec1 > rec2
320
 *
321
 *-------------------------------------------------------------------------
322
 */
323
static herr_t
324
H5HF__huge_bt2_indir_compare(const void *_rec1, const void *_rec2, int *result)
325
0
{
326
0
    FUNC_ENTER_PACKAGE_NOERR
327
328
0
    *result = (int)(((const H5HF_huge_bt2_indir_rec_t *)_rec1)->id -
329
0
                    ((const H5HF_huge_bt2_indir_rec_t *)_rec2)->id);
330
331
0
    FUNC_LEAVE_NOAPI(SUCCEED)
332
0
} /* H5HF__huge_bt2_indir_compare() */
333
334
/*-------------------------------------------------------------------------
335
 * Function:  H5HF__huge_bt2_indir_encode
336
 *
337
 * Purpose: Encode native information into raw form for storing on disk
338
 *
339
 * Return:  Success:  non-negative
340
 *    Failure:  negative
341
 *
342
 *-------------------------------------------------------------------------
343
 */
344
static herr_t
345
H5HF__huge_bt2_indir_encode(uint8_t *raw, const void *_nrecord, void *_ctx)
346
0
{
347
0
    H5HF_huge_bt2_ctx_t             *ctx     = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
348
0
    const H5HF_huge_bt2_indir_rec_t *nrecord = (const H5HF_huge_bt2_indir_rec_t *)_nrecord;
349
350
0
    FUNC_ENTER_PACKAGE_NOERR
351
352
    /* Sanity check */
353
0
    assert(ctx);
354
355
    /* Encode the record's fields */
356
0
    H5F_addr_encode_len(ctx->sizeof_addr, &raw, nrecord->addr);
357
0
    H5_ENCODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
358
0
    H5_ENCODE_LENGTH_LEN(raw, nrecord->id, ctx->sizeof_size);
359
360
0
    FUNC_LEAVE_NOAPI(SUCCEED)
361
0
} /* H5HF__huge_bt2_indir_encode() */
362
363
/*-------------------------------------------------------------------------
364
 * Function:  H5HF__huge_bt2_indir_decode
365
 *
366
 * Purpose: Decode raw disk form of record into native form
367
 *
368
 * Return:  Success:  non-negative
369
 *    Failure:  negative
370
 *
371
 *-------------------------------------------------------------------------
372
 */
373
static herr_t
374
H5HF__huge_bt2_indir_decode(const uint8_t *raw, void *_nrecord, void *_ctx)
375
0
{
376
0
    H5HF_huge_bt2_ctx_t       *ctx     = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
377
0
    H5HF_huge_bt2_indir_rec_t *nrecord = (H5HF_huge_bt2_indir_rec_t *)_nrecord;
378
379
0
    FUNC_ENTER_PACKAGE_NOERR
380
381
    /* Sanity check */
382
0
    assert(ctx);
383
384
    /* Decode the record's fields */
385
0
    H5F_addr_decode_len(ctx->sizeof_addr, &raw, &nrecord->addr);
386
0
    H5_DECODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
387
0
    H5_DECODE_LENGTH_LEN(raw, nrecord->id, ctx->sizeof_size);
388
389
0
    FUNC_LEAVE_NOAPI(SUCCEED)
390
0
} /* H5HF__huge_bt2_indir_decode() */
391
392
/*-------------------------------------------------------------------------
393
 * Function:  H5HF__huge_bt2_indir_debug
394
 *
395
 * Purpose: Debug native form of record
396
 *
397
 * Return:  Success:  non-negative
398
 *    Failure:  negative
399
 *
400
 *-------------------------------------------------------------------------
401
 */
402
static herr_t
403
H5HF__huge_bt2_indir_debug(FILE *stream, int indent, int fwidth, const void *_nrecord,
404
                           const void H5_ATTR_UNUSED *_udata)
405
0
{
406
0
    const H5HF_huge_bt2_indir_rec_t *nrecord = (const H5HF_huge_bt2_indir_rec_t *)_nrecord;
407
408
0
    FUNC_ENTER_PACKAGE_NOERR
409
410
0
    fprintf(stream, "%*s%-*s {%" PRIuHADDR ", %" PRIuHSIZE ", %" PRIuHSIZE "}\n", indent, "", fwidth,
411
0
            "Record:", nrecord->addr, nrecord->len, nrecord->id);
412
413
0
    FUNC_LEAVE_NOAPI(SUCCEED)
414
0
} /* H5HF__huge_bt2_indir_debug() */
415
416
/*-------------------------------------------------------------------------
417
 * Function:  H5HF__huge_bt2_filt_indir_found
418
 *
419
 * Purpose: Retrieve record for indirectly accessed, filtered 'huge' object,
420
 *              when it's found in the v2 B-tree
421
 *
422
 * Return:  Success:  non-negative
423
 *    Failure:  negative
424
 *
425
 *-------------------------------------------------------------------------
426
 */
427
herr_t
428
H5HF__huge_bt2_filt_indir_found(const void *nrecord, void *op_data)
429
0
{
430
0
    FUNC_ENTER_PACKAGE_NOERR
431
432
0
    *(H5HF_huge_bt2_filt_indir_rec_t *)op_data = *(const H5HF_huge_bt2_filt_indir_rec_t *)nrecord;
433
434
0
    FUNC_LEAVE_NOAPI(SUCCEED)
435
0
} /* H5HF__huge_bt2_filt_indir_found() */
436
437
/*-------------------------------------------------------------------------
438
 * Function:  H5HF__huge_bt2_filt_indir_remove
439
 *
440
 * Purpose: Free space for indirectly accessed, filtered 'huge' object, as
441
 *              v2 B-tree is being deleted or v2 B-tree node is removed
442
 *
443
 * Return:  Success:  non-negative
444
 *    Failure:  negative
445
 *
446
 *-------------------------------------------------------------------------
447
 */
448
herr_t
449
H5HF__huge_bt2_filt_indir_remove(const void *nrecord, void *_udata)
450
0
{
451
0
    H5HF_huge_remove_ud_t *udata     = (H5HF_huge_remove_ud_t *)_udata; /* User callback data */
452
0
    herr_t                 ret_value = SUCCEED;                         /* Return value */
453
454
0
    FUNC_ENTER_PACKAGE
455
456
    /* Free the space in the file for the object being removed */
457
0
    if (H5MF_xfree(udata->hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ,
458
0
                   ((const H5HF_huge_bt2_filt_indir_rec_t *)nrecord)->addr,
459
0
                   ((const H5HF_huge_bt2_filt_indir_rec_t *)nrecord)->len) < 0)
460
0
        HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free space for huge object on disk");
461
462
    /* Set the length of the object removed */
463
0
    udata->obj_len = ((const H5HF_huge_bt2_filt_indir_rec_t *)nrecord)->obj_size;
464
465
0
done:
466
0
    FUNC_LEAVE_NOAPI(ret_value)
467
0
} /* H5HF__huge_bt2_filt_indir_remove() */
468
469
/*-------------------------------------------------------------------------
470
 * Function:  H5HF__huge_bt2_filt_indir_store
471
 *
472
 * Purpose: Store native information into record for v2 B-tree
473
 *
474
 * Return:  Success:  non-negative
475
 *    Failure:  negative
476
 *
477
 *-------------------------------------------------------------------------
478
 */
479
static herr_t
480
H5HF__huge_bt2_filt_indir_store(void *nrecord, const void *udata)
481
0
{
482
0
    FUNC_ENTER_PACKAGE_NOERR
483
484
0
    *(H5HF_huge_bt2_filt_indir_rec_t *)nrecord = *(const H5HF_huge_bt2_filt_indir_rec_t *)udata;
485
486
0
    FUNC_LEAVE_NOAPI(SUCCEED)
487
0
} /* H5HF__huge_bt2_filt_indir_store() */
488
489
/*-------------------------------------------------------------------------
490
 * Function:  H5HF__huge_bt2_filt_indir_compare
491
 *
492
 * Purpose: Compare two native information records, according to some key
493
 *
494
 * Return:  <0 if rec1 < rec2
495
 *              =0 if rec1 == rec2
496
 *              >0 if rec1 > rec2
497
 *
498
 *-------------------------------------------------------------------------
499
 */
500
static herr_t
501
H5HF__huge_bt2_filt_indir_compare(const void *_rec1, const void *_rec2, int *result)
502
0
{
503
0
    FUNC_ENTER_PACKAGE_NOERR
504
505
0
    *result = (int)(((const H5HF_huge_bt2_filt_indir_rec_t *)_rec1)->id -
506
0
                    ((const H5HF_huge_bt2_filt_indir_rec_t *)_rec2)->id);
507
508
0
    FUNC_LEAVE_NOAPI(SUCCEED)
509
0
} /* H5HF__huge_bt2_filt_indir_compare() */
510
511
/*-------------------------------------------------------------------------
512
 * Function:  H5HF__huge_bt2_filt_indir_encode
513
 *
514
 * Purpose: Encode native information into raw form for storing on disk
515
 *
516
 * Return:  Success:  non-negative
517
 *    Failure:  negative
518
 *
519
 *-------------------------------------------------------------------------
520
 */
521
static herr_t
522
H5HF__huge_bt2_filt_indir_encode(uint8_t *raw, const void *_nrecord, void *_ctx)
523
0
{
524
0
    H5HF_huge_bt2_ctx_t                  *ctx = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
525
0
    const H5HF_huge_bt2_filt_indir_rec_t *nrecord = (const H5HF_huge_bt2_filt_indir_rec_t *)_nrecord;
526
527
0
    FUNC_ENTER_PACKAGE_NOERR
528
529
    /* Sanity check */
530
0
    assert(ctx);
531
532
    /* Encode the record's fields */
533
0
    H5F_addr_encode_len(ctx->sizeof_addr, &raw, nrecord->addr);
534
0
    H5_ENCODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
535
0
    UINT32ENCODE(raw, nrecord->filter_mask);
536
0
    H5_ENCODE_LENGTH_LEN(raw, nrecord->obj_size, ctx->sizeof_size);
537
0
    H5_ENCODE_LENGTH_LEN(raw, nrecord->id, ctx->sizeof_size);
538
539
0
    FUNC_LEAVE_NOAPI(SUCCEED)
540
0
} /* H5HF__huge_bt2_filt_indir_encode() */
541
542
/*-------------------------------------------------------------------------
543
 * Function:  H5HF__huge_bt2_filt_indir_decode
544
 *
545
 * Purpose: Decode raw disk form of record into native form
546
 *
547
 * Return:  Success:  non-negative
548
 *    Failure:  negative
549
 *
550
 *-------------------------------------------------------------------------
551
 */
552
static herr_t
553
H5HF__huge_bt2_filt_indir_decode(const uint8_t *raw, void *_nrecord, void *_ctx)
554
0
{
555
0
    H5HF_huge_bt2_ctx_t            *ctx     = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
556
0
    H5HF_huge_bt2_filt_indir_rec_t *nrecord = (H5HF_huge_bt2_filt_indir_rec_t *)_nrecord;
557
558
0
    FUNC_ENTER_PACKAGE_NOERR
559
560
    /* Sanity check */
561
0
    assert(ctx);
562
563
    /* Decode the record's fields */
564
0
    H5F_addr_decode_len(ctx->sizeof_addr, &raw, &nrecord->addr);
565
0
    H5_DECODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
566
0
    UINT32DECODE(raw, nrecord->filter_mask);
567
0
    H5_DECODE_LENGTH_LEN(raw, nrecord->obj_size, ctx->sizeof_size);
568
0
    H5_DECODE_LENGTH_LEN(raw, nrecord->id, ctx->sizeof_size);
569
570
0
    FUNC_LEAVE_NOAPI(SUCCEED)
571
0
} /* H5HF__huge_bt2_filt_indir_decode() */
572
573
/*-------------------------------------------------------------------------
574
 * Function:  H5HF__huge_bt2_filt_indir_debug
575
 *
576
 * Purpose: Debug native form of record
577
 *
578
 * Return:  Success:  non-negative
579
 *    Failure:  negative
580
 *
581
 *-------------------------------------------------------------------------
582
 */
583
static herr_t
584
H5HF__huge_bt2_filt_indir_debug(FILE *stream, int indent, int fwidth, const void *_nrecord,
585
                                const void H5_ATTR_UNUSED *_udata)
586
0
{
587
0
    const H5HF_huge_bt2_filt_indir_rec_t *nrecord = (const H5HF_huge_bt2_filt_indir_rec_t *)_nrecord;
588
589
0
    FUNC_ENTER_PACKAGE_NOERR
590
591
0
    fprintf(stream, "%*s%-*s {%" PRIuHADDR ", %" PRIuHSIZE ", %x, %" PRIuHSIZE ", %" PRIuHSIZE "}\n", indent,
592
0
            "", fwidth, "Record:", nrecord->addr, nrecord->len, nrecord->filter_mask, nrecord->obj_size,
593
0
            nrecord->id);
594
595
0
    FUNC_LEAVE_NOAPI(SUCCEED)
596
0
} /* H5HF__huge_bt2_filt_indir_debug() */
597
598
/*-------------------------------------------------------------------------
599
 * Function:  H5HF__huge_bt2_dir_remove
600
 *
601
 * Purpose: Free space for directly accessed 'huge' object, as v2 B-tree
602
 *              is being deleted or v2 B-tree node is being removed
603
 *
604
 * Return:  Success:  non-negative
605
 *    Failure:  negative
606
 *
607
 *-------------------------------------------------------------------------
608
 */
609
herr_t
610
H5HF__huge_bt2_dir_remove(const void *nrecord, void *_udata)
611
0
{
612
0
    H5HF_huge_remove_ud_t *udata     = (H5HF_huge_remove_ud_t *)_udata; /* User callback data */
613
0
    herr_t                 ret_value = SUCCEED;                         /* Return value */
614
615
0
    FUNC_ENTER_PACKAGE
616
617
    /* Free the space in the file for the object being removed */
618
0
    if (H5MF_xfree(udata->hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->addr,
619
0
                   ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->len) < 0)
620
0
        HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free space for huge object on disk");
621
622
    /* Set the length of the object removed */
623
0
    udata->obj_len = ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->len;
624
625
0
done:
626
0
    FUNC_LEAVE_NOAPI(ret_value)
627
0
} /* H5HF__huge_bt2_dir_remove() */
628
629
/*-------------------------------------------------------------------------
630
 * Function:  H5HF__huge_bt2_dir_store
631
 *
632
 * Purpose: Store native information into record for v2 B-tree
633
 *
634
 * Return:  Success:  non-negative
635
 *    Failure:  negative
636
 *
637
 *-------------------------------------------------------------------------
638
 */
639
static herr_t
640
H5HF__huge_bt2_dir_store(void *nrecord, const void *udata)
641
0
{
642
0
    FUNC_ENTER_PACKAGE_NOERR
643
644
0
    *(H5HF_huge_bt2_dir_rec_t *)nrecord = *(const H5HF_huge_bt2_dir_rec_t *)udata;
645
646
0
    FUNC_LEAVE_NOAPI(SUCCEED)
647
0
} /* H5HF__huge_bt2_dir_store() */
648
649
/*-------------------------------------------------------------------------
650
 * Function:  H5HF__huge_bt2_dir_compare
651
 *
652
 * Purpose: Compare two native information records, according to some key
653
 *
654
 * Return:  <0 if rec1 < rec2
655
 *              =0 if rec1 == rec2
656
 *              >0 if rec1 > rec2
657
 *
658
 *-------------------------------------------------------------------------
659
 */
660
static herr_t
661
H5HF__huge_bt2_dir_compare(const void *_rec1, const void *_rec2, int *result)
662
0
{
663
0
    const H5HF_huge_bt2_dir_rec_t *rec1 = (const H5HF_huge_bt2_dir_rec_t *)_rec1;
664
0
    const H5HF_huge_bt2_dir_rec_t *rec2 = (const H5HF_huge_bt2_dir_rec_t *)_rec2;
665
666
0
    FUNC_ENTER_PACKAGE_NOERR
667
668
0
    if (rec1->addr < rec2->addr)
669
0
        *result = -1;
670
0
    else if (rec1->addr > rec2->addr)
671
0
        *result = 1;
672
0
    else if (rec1->len < rec2->len)
673
0
        *result = -1;
674
0
    else if (rec1->len > rec2->len)
675
0
        *result = 1;
676
0
    else
677
0
        *result = 0;
678
679
0
    FUNC_LEAVE_NOAPI(SUCCEED)
680
0
} /* H5HF__huge_bt2_dir_compare() */
681
682
/*-------------------------------------------------------------------------
683
 * Function:  H5HF__huge_bt2_dir_encode
684
 *
685
 * Purpose: Encode native information into raw form for storing on disk
686
 *
687
 * Return:  Success:  non-negative
688
 *    Failure:  negative
689
 *
690
 *-------------------------------------------------------------------------
691
 */
692
static herr_t
693
H5HF__huge_bt2_dir_encode(uint8_t *raw, const void *_nrecord, void *_ctx)
694
0
{
695
0
    H5HF_huge_bt2_ctx_t           *ctx     = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
696
0
    const H5HF_huge_bt2_dir_rec_t *nrecord = (const H5HF_huge_bt2_dir_rec_t *)_nrecord;
697
698
0
    FUNC_ENTER_PACKAGE_NOERR
699
700
    /* Sanity check */
701
0
    assert(ctx);
702
703
    /* Encode the record's fields */
704
0
    H5F_addr_encode_len(ctx->sizeof_addr, &raw, nrecord->addr);
705
0
    H5_ENCODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
706
707
0
    FUNC_LEAVE_NOAPI(SUCCEED)
708
0
} /* H5HF__huge_bt2_dir_encode() */
709
710
/*-------------------------------------------------------------------------
711
 * Function:  H5HF__huge_bt2_dir_decode
712
 *
713
 * Purpose: Decode raw disk form of record into native form
714
 *
715
 * Return:  Success:  non-negative
716
 *    Failure:  negative
717
 *
718
 *-------------------------------------------------------------------------
719
 */
720
static herr_t
721
H5HF__huge_bt2_dir_decode(const uint8_t *raw, void *_nrecord, void *_ctx)
722
0
{
723
0
    H5HF_huge_bt2_ctx_t     *ctx     = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
724
0
    H5HF_huge_bt2_dir_rec_t *nrecord = (H5HF_huge_bt2_dir_rec_t *)_nrecord;
725
726
0
    FUNC_ENTER_PACKAGE_NOERR
727
728
    /* Sanity check */
729
0
    assert(ctx);
730
731
    /* Decode the record's fields */
732
0
    H5F_addr_decode_len(ctx->sizeof_addr, &raw, &nrecord->addr);
733
0
    H5_DECODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
734
735
0
    FUNC_LEAVE_NOAPI(SUCCEED)
736
0
} /* H5HF__huge_bt2_dir_decode() */
737
738
/*-------------------------------------------------------------------------
739
 * Function:  H5HF__huge_bt2_dir_debug
740
 *
741
 * Purpose: Debug native form of record
742
 *
743
 * Return:  Success:  non-negative
744
 *    Failure:  negative
745
 *
746
 *-------------------------------------------------------------------------
747
 */
748
static herr_t
749
H5HF__huge_bt2_dir_debug(FILE *stream, int indent, int fwidth, const void *_nrecord,
750
                         const void H5_ATTR_UNUSED *_udata)
751
0
{
752
0
    const H5HF_huge_bt2_dir_rec_t *nrecord = (const H5HF_huge_bt2_dir_rec_t *)_nrecord;
753
754
0
    FUNC_ENTER_PACKAGE_NOERR
755
756
0
    fprintf(stream, "%*s%-*s {%" PRIuHADDR ", %" PRIuHSIZE "}\n", indent, "", fwidth,
757
0
            "Record:", nrecord->addr, nrecord->len);
758
759
0
    FUNC_LEAVE_NOAPI(SUCCEED)
760
0
} /* H5HF__huge_bt2_dir_debug() */
761
762
/*-------------------------------------------------------------------------
763
 * Function:  H5HF__huge_bt2_filt_dir_found
764
 *
765
 * Purpose: Retrieve record for directly accessed, filtered 'huge' object,
766
 *              when it's found in the v2 B-tree
767
 *
768
 * Return:  Success:  non-negative
769
 *    Failure:  negative
770
 *
771
 *-------------------------------------------------------------------------
772
 */
773
herr_t
774
H5HF__huge_bt2_filt_dir_found(const void *nrecord, void *op_data)
775
0
{
776
0
    FUNC_ENTER_PACKAGE_NOERR
777
778
0
    *(H5HF_huge_bt2_filt_dir_rec_t *)op_data = *(const H5HF_huge_bt2_filt_dir_rec_t *)nrecord;
779
780
0
    FUNC_LEAVE_NOAPI(SUCCEED)
781
0
} /* H5HF__huge_bt2_filt_dir_found() */
782
783
/*-------------------------------------------------------------------------
784
 * Function:  H5HF__huge_bt2_filt_dir_remove
785
 *
786
 * Purpose: Free space for directly accessed, filtered 'huge' object, as
787
 *              v2 B-tree is being deleted or v2 B-tree node is removed
788
 *
789
 * Return:  Success:  non-negative
790
 *    Failure:  negative
791
 *
792
 *-------------------------------------------------------------------------
793
 */
794
herr_t
795
H5HF__huge_bt2_filt_dir_remove(const void *nrecord, void *_udata)
796
0
{
797
0
    H5HF_huge_remove_ud_t *udata     = (H5HF_huge_remove_ud_t *)_udata; /* User callback data */
798
0
    herr_t                 ret_value = SUCCEED;                         /* Return value */
799
800
0
    FUNC_ENTER_PACKAGE
801
802
    /* Free the space in the file for the object being removed */
803
0
    if (H5MF_xfree(udata->hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ,
804
0
                   ((const H5HF_huge_bt2_filt_dir_rec_t *)nrecord)->addr,
805
0
                   ((const H5HF_huge_bt2_filt_dir_rec_t *)nrecord)->len) < 0)
806
0
        HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free space for huge object on disk");
807
808
    /* Set the length of the object removed */
809
0
    udata->obj_len = ((const H5HF_huge_bt2_filt_dir_rec_t *)nrecord)->obj_size;
810
811
0
done:
812
0
    FUNC_LEAVE_NOAPI(ret_value)
813
0
} /* H5HF__huge_bt2_filt_dir_remove() */
814
815
/*-------------------------------------------------------------------------
816
 * Function:  H5HF__huge_bt2_filt_dir_store
817
 *
818
 * Purpose: Store native information into record for v2 B-tree
819
 *
820
 * Return:  Success:  non-negative
821
 *    Failure:  negative
822
 *
823
 *-------------------------------------------------------------------------
824
 */
825
static herr_t
826
H5HF__huge_bt2_filt_dir_store(void *nrecord, const void *udata)
827
0
{
828
0
    FUNC_ENTER_PACKAGE_NOERR
829
830
0
    *(H5HF_huge_bt2_filt_dir_rec_t *)nrecord = *(const H5HF_huge_bt2_filt_dir_rec_t *)udata;
831
832
0
    FUNC_LEAVE_NOAPI(SUCCEED)
833
0
} /* H5HF__huge_bt2_filt_dir_store() */
834
835
/*-------------------------------------------------------------------------
836
 * Function:  H5HF__huge_bt2_filt_dir_compare
837
 *
838
 * Purpose: Compare two native information records, according to some key
839
 *
840
 * Return:  <0 if rec1 < rec2
841
 *              =0 if rec1 == rec2
842
 *              >0 if rec1 > rec2
843
 *
844
 *-------------------------------------------------------------------------
845
 */
846
static herr_t
847
H5HF__huge_bt2_filt_dir_compare(const void *_rec1, const void *_rec2, int *result)
848
0
{
849
0
    const H5HF_huge_bt2_filt_dir_rec_t *rec1 = (const H5HF_huge_bt2_filt_dir_rec_t *)_rec1;
850
0
    const H5HF_huge_bt2_filt_dir_rec_t *rec2 = (const H5HF_huge_bt2_filt_dir_rec_t *)_rec2;
851
852
0
    FUNC_ENTER_PACKAGE_NOERR
853
854
0
    if (rec1->addr < rec2->addr)
855
0
        *result = -1;
856
0
    else if (rec1->addr > rec2->addr)
857
0
        *result = 1;
858
0
    else if (rec1->len < rec2->len)
859
0
        *result = -1;
860
0
    else if (rec1->len > rec2->len)
861
0
        *result = 1;
862
0
    else
863
0
        *result = 0;
864
865
0
    FUNC_LEAVE_NOAPI(SUCCEED)
866
0
} /* H5HF__huge_bt2_filt_dir_compare() */
867
868
/*-------------------------------------------------------------------------
869
 * Function:  H5HF__huge_bt2_filt_dir_encode
870
 *
871
 * Purpose: Encode native information into raw form for storing on disk
872
 *
873
 * Return:  Success:  non-negative
874
 *    Failure:  negative
875
 *
876
 *-------------------------------------------------------------------------
877
 */
878
static herr_t
879
H5HF__huge_bt2_filt_dir_encode(uint8_t *raw, const void *_nrecord, void *_ctx)
880
0
{
881
0
    H5HF_huge_bt2_ctx_t                *ctx = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
882
0
    const H5HF_huge_bt2_filt_dir_rec_t *nrecord = (const H5HF_huge_bt2_filt_dir_rec_t *)_nrecord;
883
884
0
    FUNC_ENTER_PACKAGE_NOERR
885
886
    /* Sanity check */
887
0
    assert(ctx);
888
889
    /* Encode the record's fields */
890
0
    H5F_addr_encode_len(ctx->sizeof_addr, &raw, nrecord->addr);
891
0
    H5_ENCODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
892
0
    UINT32ENCODE(raw, nrecord->filter_mask);
893
0
    H5_ENCODE_LENGTH_LEN(raw, nrecord->obj_size, ctx->sizeof_size);
894
895
0
    FUNC_LEAVE_NOAPI(SUCCEED)
896
0
} /* H5HF__huge_bt2_filt_dir_encode() */
897
898
/*-------------------------------------------------------------------------
899
 * Function:  H5HF__huge_bt2_filt_dir_decode
900
 *
901
 * Purpose: Decode raw disk form of record into native form
902
 *
903
 * Return:  Success:  non-negative
904
 *    Failure:  negative
905
 *
906
 *-------------------------------------------------------------------------
907
 */
908
static herr_t
909
H5HF__huge_bt2_filt_dir_decode(const uint8_t *raw, void *_nrecord, void *_ctx)
910
0
{
911
0
    H5HF_huge_bt2_ctx_t          *ctx     = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
912
0
    H5HF_huge_bt2_filt_dir_rec_t *nrecord = (H5HF_huge_bt2_filt_dir_rec_t *)_nrecord;
913
914
0
    FUNC_ENTER_PACKAGE_NOERR
915
916
    /* Sanity check */
917
0
    assert(ctx);
918
919
    /* Decode the record's fields */
920
0
    H5F_addr_decode_len(ctx->sizeof_addr, &raw, &nrecord->addr);
921
0
    H5_DECODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
922
0
    UINT32DECODE(raw, nrecord->filter_mask);
923
0
    H5_DECODE_LENGTH_LEN(raw, nrecord->obj_size, ctx->sizeof_size);
924
925
0
    FUNC_LEAVE_NOAPI(SUCCEED)
926
0
} /* H5HF__huge_bt2_filt_dir_decode() */
927
928
/*-------------------------------------------------------------------------
929
 * Function:  H5HF__huge_bt2_filt_dir_debug
930
 *
931
 * Purpose: Debug native form of record
932
 *
933
 * Return:  Success:  non-negative
934
 *    Failure:  negative
935
 *
936
 *-------------------------------------------------------------------------
937
 */
938
static herr_t
939
H5HF__huge_bt2_filt_dir_debug(FILE *stream, int indent, int fwidth, const void *_nrecord,
940
                              const void H5_ATTR_UNUSED *_udata)
941
0
{
942
0
    const H5HF_huge_bt2_filt_dir_rec_t *nrecord = (const H5HF_huge_bt2_filt_dir_rec_t *)_nrecord;
943
944
0
    FUNC_ENTER_PACKAGE_NOERR
945
946
0
    fprintf(stream, "%*s%-*s {%" PRIuHADDR ", %" PRIuHSIZE ", %x, %" PRIuHSIZE "}\n", indent, "", fwidth,
947
0
            "Record:", nrecord->addr, nrecord->len, nrecord->filter_mask, nrecord->obj_size);
948
949
0
    FUNC_LEAVE_NOAPI(SUCCEED)
950
0
} /* H5HF__huge_bt2_filt_dir_debug() */