/src/hdf5/src/H5Gcompact.c
Line | Count | Source |
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: H5Gcompact.c |
16 | | * |
17 | | * Purpose: Functions for handling compact storage. |
18 | | * |
19 | | *------------------------------------------------------------------------- |
20 | | */ |
21 | | #include "H5Gmodule.h" /* This source code file is part of the H5G module */ |
22 | | |
23 | | /* Packages needed by this file... */ |
24 | | #include "H5private.h" /* Generic Functions */ |
25 | | #include "H5Eprivate.h" /* Error handling */ |
26 | | #include "H5Gpkg.h" /* Groups */ |
27 | | #include "H5MMprivate.h" /* Memory management */ |
28 | | |
29 | | /* Private typedefs */ |
30 | | |
31 | | /* User data for link message iteration when building link table */ |
32 | | typedef struct { |
33 | | H5G_link_table_t *ltable; /* Pointer to link table to build */ |
34 | | size_t curr_lnk; /* Current link to operate on */ |
35 | | } H5G_iter_bt_t; |
36 | | |
37 | | /* User data for deleting a link in the link messages */ |
38 | | typedef struct { |
39 | | /* downward */ |
40 | | H5F_t *file; /* File that object header is located within */ |
41 | | H5RS_str_t *grp_full_path_r; /* Full path for group of link */ |
42 | | const char *name; /* Link name to search for */ |
43 | | } H5G_iter_rm_t; |
44 | | |
45 | | /* User data for link message iteration when querying link info */ |
46 | | typedef struct { |
47 | | /* downward */ |
48 | | const char *name; /* Name to search for */ |
49 | | |
50 | | /* upward */ |
51 | | H5O_link_t *lnk; /* Link struct to fill in */ |
52 | | bool *found; /* Pointer to flag to indicate that the object was found */ |
53 | | } H5G_iter_lkp_t; |
54 | | |
55 | | /* Private macros */ |
56 | | |
57 | | /* PRIVATE PROTOTYPES */ |
58 | | static herr_t H5G__compact_build_table_cb(const void *_mesg, unsigned idx, void *_udata); |
59 | | static herr_t H5G__compact_build_table(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, |
60 | | H5_iter_order_t order, H5G_link_table_t *ltable); |
61 | | static herr_t H5G__compact_lookup_cb(const void *_mesg, unsigned H5_ATTR_UNUSED idx, void *_udata); |
62 | | |
63 | | /*------------------------------------------------------------------------- |
64 | | * Function: H5G__compact_build_table_cb |
65 | | * |
66 | | * Purpose: Callback routine for searching 'link' messages for a particular |
67 | | * name. |
68 | | * |
69 | | * Return: SUCCEED/FAIL |
70 | | * |
71 | | *------------------------------------------------------------------------- |
72 | | */ |
73 | | static herr_t |
74 | | H5G__compact_build_table_cb(const void *_mesg, unsigned H5_ATTR_UNUSED idx, void *_udata) |
75 | 0 | { |
76 | 0 | const H5O_link_t *lnk = (const H5O_link_t *)_mesg; /* Pointer to link */ |
77 | 0 | H5G_iter_bt_t *udata = (H5G_iter_bt_t *)_udata; /* 'User data' passed in */ |
78 | 0 | herr_t ret_value = H5_ITER_CONT; /* Return value */ |
79 | |
|
80 | 0 | FUNC_ENTER_PACKAGE |
81 | | |
82 | | /* check arguments */ |
83 | 0 | assert(lnk); |
84 | 0 | assert(udata); |
85 | 0 | assert(udata->curr_lnk < udata->ltable->nlinks); |
86 | | |
87 | | /* Copy link message into table */ |
88 | 0 | if (NULL == H5O_msg_copy(H5O_LINK_ID, lnk, &(udata->ltable->lnks[udata->curr_lnk]))) |
89 | 0 | HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy link message"); |
90 | | |
91 | | /* Increment current link entry to operate on */ |
92 | 0 | udata->curr_lnk++; |
93 | |
|
94 | 0 | done: |
95 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
96 | 0 | } /* end H5G__compact_build_table_cb() */ |
97 | | |
98 | | /*------------------------------------------------------------------------- |
99 | | * Function: H5G__compact_build_table |
100 | | * |
101 | | * Purpose: Builds a table containing a sorted (alphabetically) list of |
102 | | * links for a group |
103 | | * |
104 | | * Return: Success: Non-negative |
105 | | * Failure: Negative |
106 | | * |
107 | | *------------------------------------------------------------------------- |
108 | | */ |
109 | | static herr_t |
110 | | H5G__compact_build_table(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, |
111 | | H5_iter_order_t order, H5G_link_table_t *ltable) |
112 | 0 | { |
113 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
114 | |
|
115 | 0 | FUNC_ENTER_PACKAGE |
116 | | |
117 | | /* Sanity check */ |
118 | 0 | assert(oloc); |
119 | 0 | assert(linfo); |
120 | 0 | assert(ltable); |
121 | | |
122 | | /* Set size of table */ |
123 | 0 | H5_CHECK_OVERFLOW(linfo->nlinks, hsize_t, size_t); |
124 | 0 | ltable->nlinks = (size_t)linfo->nlinks; |
125 | | |
126 | | /* Allocate space for the table entries */ |
127 | 0 | if (ltable->nlinks > 0) { |
128 | 0 | H5G_iter_bt_t udata; /* User data for iteration callback */ |
129 | 0 | H5O_mesg_operator_t op; /* Message operator */ |
130 | | |
131 | | /* Allocate the link table */ |
132 | 0 | if ((ltable->lnks = (H5O_link_t *)H5MM_calloc(sizeof(H5O_link_t) * ltable->nlinks)) == NULL) |
133 | 0 | HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); |
134 | | |
135 | | /* Set up user data for iteration */ |
136 | 0 | udata.ltable = ltable; |
137 | 0 | udata.curr_lnk = 0; |
138 | | |
139 | | /* Iterate through the link messages, adding them to the table */ |
140 | 0 | op.op_type = H5O_MESG_OP_APP; |
141 | 0 | op.u.app_op = H5G__compact_build_table_cb; |
142 | 0 | if (H5O_msg_iterate(oloc, H5O_LINK_ID, &op, &udata) < 0) |
143 | 0 | HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over link messages"); |
144 | | |
145 | | /* Sort link table in correct iteration order */ |
146 | 0 | if (H5G__link_sort_table(ltable, idx_type, order) < 0) |
147 | 0 | HGOTO_ERROR(H5E_SYM, H5E_CANTSORT, FAIL, "error sorting link messages"); |
148 | 0 | } /* end if */ |
149 | 0 | else |
150 | 0 | ltable->lnks = NULL; |
151 | | |
152 | 0 | done: |
153 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
154 | 0 | } /* end H5G__compact_build_table() */ |
155 | | |
156 | | /*------------------------------------------------------------------------- |
157 | | * Function: H5G__compact_insert |
158 | | * |
159 | | * Purpose: Insert a new symbol into the table described by GRP_ENT in |
160 | | * file F. The name of the new symbol is NAME and its symbol |
161 | | * table entry is OBJ_ENT. |
162 | | * |
163 | | * Return: Non-negative on success/Negative on failure |
164 | | * |
165 | | *------------------------------------------------------------------------- |
166 | | */ |
167 | | herr_t |
168 | | H5G__compact_insert(const H5O_loc_t *grp_oloc, H5O_link_t *obj_lnk) |
169 | 0 | { |
170 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
171 | |
|
172 | 0 | FUNC_ENTER_PACKAGE |
173 | | |
174 | | /* check arguments */ |
175 | 0 | assert(grp_oloc && grp_oloc->file); |
176 | 0 | assert(obj_lnk); |
177 | | |
178 | | /* Insert link message into group */ |
179 | 0 | if (H5O_msg_create(grp_oloc, H5O_LINK_ID, 0, H5O_UPDATE_TIME, obj_lnk) < 0) |
180 | 0 | HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message"); |
181 | | |
182 | 0 | done: |
183 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
184 | 0 | } /* end H5G__compact_insert() */ |
185 | | |
186 | | /*------------------------------------------------------------------------- |
187 | | * Function: H5G__compact_get_name_by_idx |
188 | | * |
189 | | * Purpose: Returns the name of objects in the group by giving index. |
190 | | * |
191 | | * Return: Non-negative on success/Negative on failure |
192 | | * |
193 | | *------------------------------------------------------------------------- |
194 | | */ |
195 | | herr_t |
196 | | H5G__compact_get_name_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, |
197 | | H5_iter_order_t order, hsize_t idx, char *name, size_t name_size, |
198 | | size_t *name_len) |
199 | 0 | { |
200 | 0 | H5G_link_table_t ltable = {0, NULL}; /* Link table */ |
201 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
202 | |
|
203 | 0 | FUNC_ENTER_PACKAGE |
204 | | |
205 | | /* Sanity check */ |
206 | 0 | assert(oloc); |
207 | | |
208 | | /* Build table of all link messages */ |
209 | 0 | if (H5G__compact_build_table(oloc, linfo, idx_type, order, <able) < 0) |
210 | 0 | HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create link message table"); |
211 | | |
212 | | /* Check for going out of bounds */ |
213 | 0 | if (idx >= ltable.nlinks) |
214 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "index out of bound"); |
215 | | |
216 | | /* Get the length of the name */ |
217 | 0 | *name_len = strlen(ltable.lnks[idx].name); |
218 | | |
219 | | /* Copy the name into the user's buffer, if given */ |
220 | 0 | if (name) { |
221 | 0 | strncpy(name, ltable.lnks[idx].name, MIN((*name_len + 1), name_size)); |
222 | 0 | if (*name_len >= name_size) |
223 | 0 | name[name_size - 1] = '\0'; |
224 | 0 | } /* end if */ |
225 | |
|
226 | 0 | done: |
227 | | /* Release link table */ |
228 | 0 | if (ltable.lnks && H5G__link_release_table(<able) < 0) |
229 | 0 | HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table"); |
230 | |
|
231 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
232 | 0 | } /* end H5G__compact_get_name_by_idx() */ |
233 | | |
234 | | /*------------------------------------------------------------------------- |
235 | | * Function: H5G__compact_remove_common_cb |
236 | | * |
237 | | * Purpose: Common callback routine for deleting 'link' message for a |
238 | | * particular name. |
239 | | * |
240 | | * Return: Non-negative on success/Negative on failure |
241 | | * |
242 | | *------------------------------------------------------------------------- |
243 | | */ |
244 | | static herr_t |
245 | | H5G__compact_remove_common_cb(const void *_mesg, unsigned H5_ATTR_UNUSED idx, void *_udata) |
246 | 0 | { |
247 | 0 | const H5O_link_t *lnk = (const H5O_link_t *)_mesg; /* Pointer to link */ |
248 | 0 | H5G_iter_rm_t *udata = (H5G_iter_rm_t *)_udata; /* 'User data' passed in */ |
249 | 0 | herr_t ret_value = H5_ITER_CONT; /* Return value */ |
250 | |
|
251 | 0 | FUNC_ENTER_PACKAGE |
252 | | |
253 | | /* check arguments */ |
254 | 0 | assert(lnk); |
255 | 0 | assert(udata); |
256 | | |
257 | | /* If we've found the right link, get the object type */ |
258 | 0 | if (strcmp(lnk->name, udata->name) == 0) { |
259 | | /* Replace path names for link being removed */ |
260 | 0 | if (H5G__link_name_replace(udata->file, udata->grp_full_path_r, lnk) < 0) |
261 | 0 | HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get object type"); |
262 | | |
263 | | /* Stop the iteration, we found the correct link */ |
264 | 0 | HGOTO_DONE(H5_ITER_STOP); |
265 | 0 | } /* end if */ |
266 | | |
267 | 0 | done: |
268 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
269 | 0 | } /* end H5G__compact_remove_common_cb() */ |
270 | | |
271 | | /*------------------------------------------------------------------------- |
272 | | * Function: H5G__compact_remove |
273 | | * |
274 | | * Purpose: Remove NAME from links. |
275 | | * |
276 | | * Return: Non-negative on success/Negative on failure |
277 | | * |
278 | | *------------------------------------------------------------------------- |
279 | | */ |
280 | | herr_t |
281 | | H5G__compact_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name) |
282 | 0 | { |
283 | 0 | H5G_iter_rm_t udata; /* Data to pass through OH iteration */ |
284 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
285 | |
|
286 | 0 | FUNC_ENTER_PACKAGE |
287 | |
|
288 | 0 | assert(oloc && oloc->file); |
289 | 0 | assert(name && *name); |
290 | | |
291 | | /* Initialize data to pass through object header iteration */ |
292 | 0 | udata.file = oloc->file; |
293 | 0 | udata.grp_full_path_r = grp_full_path_r; |
294 | 0 | udata.name = name; |
295 | | |
296 | | /* Iterate over the link messages to delete the right one */ |
297 | 0 | if (H5O_msg_remove_op(oloc, H5O_LINK_ID, H5O_FIRST, H5G__compact_remove_common_cb, &udata, true) < 0) |
298 | 0 | HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete link message"); |
299 | | |
300 | 0 | done: |
301 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
302 | 0 | } /* end H5G__compact_remove() */ |
303 | | |
304 | | /*------------------------------------------------------------------------- |
305 | | * Function: H5G__compact_remove_by_idx |
306 | | * |
307 | | * Purpose: Remove link from group, according to an index order. |
308 | | * |
309 | | * Return: Non-negative on success/Negative on failure |
310 | | * |
311 | | *------------------------------------------------------------------------- |
312 | | */ |
313 | | herr_t |
314 | | H5G__compact_remove_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r, |
315 | | H5_index_t idx_type, H5_iter_order_t order, hsize_t n) |
316 | 0 | { |
317 | 0 | H5G_link_table_t ltable = {0, NULL}; /* Link table */ |
318 | 0 | H5G_iter_rm_t udata; /* Data to pass through OH iteration */ |
319 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
320 | |
|
321 | 0 | FUNC_ENTER_PACKAGE |
322 | |
|
323 | 0 | assert(oloc && oloc->file); |
324 | 0 | assert(linfo); |
325 | | |
326 | | /* Build table of all link messages, sorted according to desired order */ |
327 | 0 | if (H5G__compact_build_table(oloc, linfo, idx_type, order, <able) < 0) |
328 | 0 | HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create link message table"); |
329 | | |
330 | | /* Check for going out of bounds */ |
331 | 0 | if (n >= ltable.nlinks) |
332 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "index out of bound"); |
333 | | |
334 | | /* Initialize data to pass through object header iteration */ |
335 | 0 | udata.file = oloc->file; |
336 | 0 | udata.grp_full_path_r = grp_full_path_r; |
337 | 0 | udata.name = ltable.lnks[n].name; |
338 | | |
339 | | /* Iterate over the link messages to delete the right one */ |
340 | 0 | if (H5O_msg_remove_op(oloc, H5O_LINK_ID, H5O_FIRST, H5G__compact_remove_common_cb, &udata, true) < 0) |
341 | 0 | HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete link message"); |
342 | | |
343 | 0 | done: |
344 | | /* Release link table */ |
345 | 0 | if (ltable.lnks && H5G__link_release_table(<able) < 0) |
346 | 0 | HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table"); |
347 | |
|
348 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
349 | 0 | } /* end H5G__compact_remove_by_idx() */ |
350 | | |
351 | | /*------------------------------------------------------------------------- |
352 | | * Function: H5G__compact_iterate |
353 | | * |
354 | | * Purpose: Iterate over the links in a group |
355 | | * |
356 | | * Return: Non-negative on success/Negative on failure |
357 | | * |
358 | | *------------------------------------------------------------------------- |
359 | | */ |
360 | | herr_t |
361 | | H5G__compact_iterate(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, |
362 | | H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, |
363 | | void *op_data) |
364 | 0 | { |
365 | 0 | H5G_link_table_t ltable = {0, NULL}; /* Link table */ |
366 | 0 | herr_t ret_value = FAIL; /* Return value */ |
367 | |
|
368 | 0 | FUNC_ENTER_PACKAGE |
369 | | |
370 | | /* Sanity check */ |
371 | 0 | assert(oloc); |
372 | 0 | assert(linfo); |
373 | 0 | assert(op); |
374 | | |
375 | | /* Build table of all link messages */ |
376 | 0 | if (H5G__compact_build_table(oloc, linfo, idx_type, order, <able) < 0) |
377 | 0 | HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create link message table"); |
378 | | |
379 | | /* Iterate over links in table */ |
380 | 0 | if ((ret_value = H5G__link_iterate_table(<able, skip, last_lnk, op, op_data)) < 0) |
381 | 0 | HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed"); |
382 | |
|
383 | 0 | done: |
384 | | /* Release link table */ |
385 | 0 | if (ltable.lnks && H5G__link_release_table(<able) < 0) |
386 | 0 | HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table"); |
387 | |
|
388 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
389 | 0 | } /* end H5G__compact_iterate() */ |
390 | | |
391 | | /*------------------------------------------------------------------------- |
392 | | * Function: H5G__compact_lookup_cb |
393 | | * |
394 | | * Purpose: Callback routine for searching 'link' messages for a particular |
395 | | * name & getting object location for it |
396 | | * |
397 | | * Return: SUCCEED/FAIL |
398 | | * |
399 | | *------------------------------------------------------------------------- |
400 | | */ |
401 | | static herr_t |
402 | | H5G__compact_lookup_cb(const void *_mesg, unsigned H5_ATTR_UNUSED idx, void *_udata) |
403 | 0 | { |
404 | 0 | const H5O_link_t *lnk = (const H5O_link_t *)_mesg; /* Pointer to link */ |
405 | 0 | H5G_iter_lkp_t *udata = (H5G_iter_lkp_t *)_udata; /* 'User data' passed in */ |
406 | 0 | herr_t ret_value = H5_ITER_CONT; /* Return value */ |
407 | |
|
408 | 0 | FUNC_ENTER_PACKAGE |
409 | | |
410 | | /* check arguments */ |
411 | 0 | assert(lnk); |
412 | 0 | assert(udata); |
413 | | |
414 | | /* Check for name to get information */ |
415 | 0 | if (strcmp(lnk->name, udata->name) == 0) { |
416 | 0 | if (udata->lnk) { |
417 | | /* Copy link information */ |
418 | 0 | if (NULL == H5O_msg_copy(H5O_LINK_ID, lnk, udata->lnk)) |
419 | 0 | HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy link message"); |
420 | 0 | } /* end if */ |
421 | | |
422 | | /* Indicate that the correct link was found */ |
423 | 0 | *udata->found = true; |
424 | | |
425 | | /* Stop iteration now */ |
426 | 0 | HGOTO_DONE(H5_ITER_STOP); |
427 | 0 | } /* end if */ |
428 | | |
429 | 0 | done: |
430 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
431 | 0 | } /* end H5G__compact_lookup_cb() */ |
432 | | |
433 | | /*------------------------------------------------------------------------- |
434 | | * Function: H5G__compact_lookup |
435 | | * |
436 | | * Purpose: Look up an object relative to a group, using link messages. |
437 | | * |
438 | | * Return: Non-negative (true/false) on success/Negative on failure |
439 | | * |
440 | | *------------------------------------------------------------------------- |
441 | | */ |
442 | | herr_t |
443 | | H5G__compact_lookup(const H5O_loc_t *oloc, const char *name, bool *found, H5O_link_t *lnk) |
444 | 0 | { |
445 | 0 | H5G_iter_lkp_t udata; /* User data for iteration callback */ |
446 | 0 | H5O_mesg_operator_t op; /* Message operator */ |
447 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
448 | |
|
449 | 0 | FUNC_ENTER_PACKAGE |
450 | | |
451 | | /* check arguments */ |
452 | 0 | assert(name && *name); |
453 | 0 | assert(found); |
454 | 0 | assert(lnk && oloc->file); |
455 | | |
456 | | /* Set up user data for iteration */ |
457 | 0 | udata.name = name; |
458 | 0 | udata.lnk = lnk; |
459 | 0 | udata.found = found; |
460 | | |
461 | | /* Iterate through the link messages, adding them to the table */ |
462 | 0 | op.op_type = H5O_MESG_OP_APP; |
463 | 0 | op.u.app_op = H5G__compact_lookup_cb; |
464 | 0 | if (H5O_msg_iterate(oloc, H5O_LINK_ID, &op, &udata) < 0) |
465 | 0 | HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over link messages"); |
466 | | |
467 | 0 | done: |
468 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
469 | 0 | } /* end H5G__compact_lookup() */ |
470 | | |
471 | | /*------------------------------------------------------------------------- |
472 | | * Function: H5G__compact_lookup_by_idx |
473 | | * |
474 | | * Purpose: Look up an object in a group using link messages, |
475 | | * according to the order of an index |
476 | | * |
477 | | * Return: Non-negative on success/Negative on failure |
478 | | * |
479 | | *------------------------------------------------------------------------- |
480 | | */ |
481 | | herr_t |
482 | | H5G__compact_lookup_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, |
483 | | H5_iter_order_t order, hsize_t n, H5O_link_t *lnk) |
484 | 0 | { |
485 | 0 | H5G_link_table_t ltable = {0, NULL}; /* Link table */ |
486 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
487 | |
|
488 | 0 | FUNC_ENTER_PACKAGE |
489 | | |
490 | | /* check arguments */ |
491 | 0 | assert(oloc && oloc->file); |
492 | 0 | assert(linfo); |
493 | 0 | assert(lnk); |
494 | | |
495 | | /* Build table of all link messages, sorted according to desired order */ |
496 | 0 | if (H5G__compact_build_table(oloc, linfo, idx_type, order, <able) < 0) |
497 | 0 | HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create link message table"); |
498 | | |
499 | | /* Check for going out of bounds */ |
500 | 0 | if (n >= ltable.nlinks) |
501 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "index out of bound"); |
502 | | |
503 | | /* Copy link information */ |
504 | 0 | if (NULL == H5O_msg_copy(H5O_LINK_ID, <able.lnks[n], lnk)) |
505 | 0 | HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy link message"); |
506 | | |
507 | 0 | done: |
508 | | /* Release link table */ |
509 | 0 | if (ltable.lnks && H5G__link_release_table(<able) < 0) |
510 | 0 | HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table"); |
511 | |
|
512 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
513 | 0 | } /* end H5G__compact_lookup_by_idx() */ |