* Fast path if we detect that all trees are the same as cache-tree at this * path. We'll walk these trees in an iterative loop using cache-tree/index * instead of ODB since we already know what these trees contain. */
| 800 | * instead of ODB since we already know what these trees contain. |
| 801 | */ |
| 802 | static int traverse_by_cache_tree(int pos, int nr_entries, int nr_names, |
| 803 | struct traverse_info *info) |
| 804 | { |
| 805 | struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, }; |
| 806 | struct unpack_trees_options *o = info->data; |
| 807 | struct cache_entry *tree_ce = NULL; |
| 808 | int ce_len = 0; |
| 809 | int i, d; |
| 810 | |
| 811 | if (!o->merge) |
| 812 | BUG("We need cache-tree to do this optimization"); |
| 813 | if (nr_entries + pos > o->src_index->cache_nr) |
| 814 | return error(_("corrupted cache-tree has entries not present in index")); |
| 815 | |
| 816 | /* |
| 817 | * Do what unpack_callback() and unpack_single_entry() normally |
| 818 | * do. But we walk all paths in an iterative loop instead. |
| 819 | * |
| 820 | * D/F conflicts and higher stage entries are not a concern |
| 821 | * because cache-tree would be invalidated and we would never |
| 822 | * get here in the first place. |
| 823 | */ |
| 824 | for (i = 0; i < nr_entries; i++) { |
| 825 | int new_ce_len, len, rc; |
| 826 | |
| 827 | src[0] = o->src_index->cache[pos + i]; |
| 828 | |
| 829 | len = ce_namelen(src[0]); |
| 830 | new_ce_len = cache_entry_size(len); |
| 831 | |
| 832 | if (new_ce_len > ce_len) { |
| 833 | new_ce_len <<= 1; |
| 834 | tree_ce = xrealloc(tree_ce, new_ce_len); |
| 835 | memset(tree_ce, 0, new_ce_len); |
| 836 | ce_len = new_ce_len; |
| 837 | |
| 838 | tree_ce->ce_flags = create_ce_flags(0); |
| 839 | |
| 840 | for (d = 1; d <= nr_names; d++) |
| 841 | src[d] = tree_ce; |
| 842 | } |
| 843 | |
| 844 | tree_ce->ce_mode = src[0]->ce_mode; |
| 845 | tree_ce->ce_namelen = len; |
| 846 | oidcpy(&tree_ce->oid, &src[0]->oid); |
| 847 | memcpy(tree_ce->name, src[0]->name, len + 1); |
| 848 | |
| 849 | rc = call_unpack_fn((const struct cache_entry * const *)src, o); |
| 850 | if (rc < 0) { |
| 851 | free(tree_ce); |
| 852 | return rc; |
| 853 | } |
| 854 | |
| 855 | mark_ce_used(src[0], o); |
| 856 | } |
| 857 | free(tree_ce); |
| 858 | if (o->internal.debug_unpack) |
| 859 | printf("Unpacked %d entries from %s to %s using cache-tree\n", |
no test coverage detected