| 560 | } |
| 561 | |
| 562 | static int for_each_note_helper(struct notes_tree *t, struct int_node *tree, |
| 563 | unsigned char n, unsigned char fanout, int flags, |
| 564 | each_note_fn fn, void *cb_data) |
| 565 | { |
| 566 | unsigned int i; |
| 567 | void *p; |
| 568 | int ret = 0; |
| 569 | struct leaf_node *l; |
| 570 | static char path[FANOUT_PATH_MAX]; |
| 571 | |
| 572 | fanout = determine_fanout(tree, n, fanout); |
| 573 | for (i = 0; i < 16; i++) { |
| 574 | redo: |
| 575 | p = tree->a[i]; |
| 576 | switch (GET_PTR_TYPE(p)) { |
| 577 | case PTR_TYPE_INTERNAL: |
| 578 | /* recurse into int_node */ |
| 579 | ret = for_each_note_helper(t, CLR_PTR_TYPE(p), n + 1, |
| 580 | fanout, flags, fn, cb_data); |
| 581 | break; |
| 582 | case PTR_TYPE_SUBTREE: |
| 583 | l = (struct leaf_node *) CLR_PTR_TYPE(p); |
| 584 | /* |
| 585 | * Subtree entries in the note tree represent parts of |
| 586 | * the note tree that have not yet been explored. There |
| 587 | * is a direct relationship between subtree entries at |
| 588 | * level 'n' in the tree, and the 'fanout' variable: |
| 589 | * Subtree entries at level 'n < 2 * fanout' should be |
| 590 | * preserved, since they correspond exactly to a fanout |
| 591 | * directory in the on-disk structure. However, subtree |
| 592 | * entries at level 'n >= 2 * fanout' should NOT be |
| 593 | * preserved, but rather consolidated into the above |
| 594 | * notes tree level. We achieve this by unconditionally |
| 595 | * unpacking subtree entries that exist below the |
| 596 | * threshold level at 'n = 2 * fanout'. |
| 597 | */ |
| 598 | if (n < 2 * fanout && |
| 599 | flags & FOR_EACH_NOTE_YIELD_SUBTREES) { |
| 600 | /* invoke callback with subtree */ |
| 601 | unsigned int path_len = |
| 602 | l->key_oid.hash[KEY_INDEX] * 2 + fanout; |
| 603 | assert(path_len < FANOUT_PATH_MAX - 1); |
| 604 | construct_path_with_fanout(l->key_oid.hash, |
| 605 | fanout, |
| 606 | path); |
| 607 | /* Create trailing slash, if needed */ |
| 608 | if (path[path_len - 1] != '/') |
| 609 | path[path_len++] = '/'; |
| 610 | path[path_len] = '\0'; |
| 611 | ret = fn(&l->key_oid, &l->val_oid, |
| 612 | path, |
| 613 | cb_data); |
| 614 | } |
| 615 | if (n >= 2 * fanout || |
| 616 | !(flags & FOR_EACH_NOTE_DONT_UNPACK_SUBTREES)) { |
| 617 | /* unpack subtree and resume traversal */ |
| 618 | tree->a[i] = NULL; |
| 619 | load_subtree(t, l, tree, n); |
no test coverage detected