Git fork
at 3deb97fe24eccb1245e9323475f10cfba705e08f 1117 lines 29 kB view raw
1#define DISABLE_SIGN_COMPARE_WARNINGS 2 3#include "git-compat-util.h" 4#include "environment.h" 5#include "gettext.h" 6#include "hex.h" 7#include "odb.h" 8#include "commit.h" 9#include "diff.h" 10#include "revision.h" 11#include "progress.h" 12#include "pack.h" 13#include "pack-bitmap.h" 14#include "hash-lookup.h" 15#include "pack-objects.h" 16#include "path.h" 17#include "commit-reach.h" 18#include "prio-queue.h" 19#include "trace2.h" 20#include "tree.h" 21#include "tree-walk.h" 22#include "pseudo-merge.h" 23#include "oid-array.h" 24#include "config.h" 25#include "alloc.h" 26#include "refs.h" 27#include "strmap.h" 28#include "midx.h" 29#include "pack-revindex.h" 30 31struct bitmapped_commit { 32 struct commit *commit; 33 struct ewah_bitmap *bitmap; 34 struct ewah_bitmap *write_as; 35 int flags; 36 int xor_offset; 37 uint32_t commit_pos; 38 unsigned pseudo_merge : 1; 39}; 40 41static inline int bitmap_writer_nr_selected_commits(struct bitmap_writer *writer) 42{ 43 return writer->selected_nr - writer->pseudo_merges_nr; 44} 45 46void bitmap_writer_init(struct bitmap_writer *writer, struct repository *r, 47 struct packing_data *pdata, 48 struct multi_pack_index *midx) 49{ 50 memset(writer, 0, sizeof(struct bitmap_writer)); 51 if (writer->bitmaps) 52 BUG("bitmap writer already initialized"); 53 writer->repo = r; 54 writer->bitmaps = kh_init_oid_map(); 55 writer->pseudo_merge_commits = kh_init_oid_map(); 56 writer->to_pack = pdata; 57 writer->midx = midx; 58 59 string_list_init_dup(&writer->pseudo_merge_groups); 60 61 load_pseudo_merges_from_config(r, &writer->pseudo_merge_groups); 62} 63 64static void free_pseudo_merge_commit_idx(struct pseudo_merge_commit_idx *idx) 65{ 66 if (!idx) 67 return; 68 free(idx->pseudo_merge); 69 free(idx); 70} 71 72static void pseudo_merge_group_release_cb(void *payload, const char *name UNUSED) 73{ 74 pseudo_merge_group_release(payload); 75 free(payload); 76} 77 78void bitmap_writer_free(struct bitmap_writer *writer) 79{ 80 uint32_t i; 81 struct pseudo_merge_commit_idx *idx; 82 83 if (!writer) 84 return; 85 86 ewah_free(writer->commits); 87 ewah_free(writer->trees); 88 ewah_free(writer->blobs); 89 ewah_free(writer->tags); 90 91 kh_destroy_oid_map(writer->bitmaps); 92 93 kh_foreach_value(writer->pseudo_merge_commits, idx, 94 free_pseudo_merge_commit_idx(idx)); 95 kh_destroy_oid_map(writer->pseudo_merge_commits); 96 string_list_clear_func(&writer->pseudo_merge_groups, 97 pseudo_merge_group_release_cb); 98 99 for (i = 0; i < writer->selected_nr; i++) { 100 struct bitmapped_commit *bc = &writer->selected[i]; 101 if (bc->write_as != bc->bitmap) 102 ewah_free(bc->write_as); 103 ewah_free(bc->bitmap); 104 } 105 free(writer->selected); 106} 107 108void bitmap_writer_show_progress(struct bitmap_writer *writer, int show) 109{ 110 writer->show_progress = show; 111} 112 113/** 114 * Build the initial type index for the packfile or multi-pack-index 115 */ 116void bitmap_writer_build_type_index(struct bitmap_writer *writer, 117 struct pack_idx_entry **index) 118{ 119 uint32_t i; 120 uint32_t base_objects = 0; 121 122 if (writer->midx) 123 base_objects = writer->midx->num_objects + 124 writer->midx->num_objects_in_base; 125 126 writer->commits = ewah_new(); 127 writer->trees = ewah_new(); 128 writer->blobs = ewah_new(); 129 writer->tags = ewah_new(); 130 ALLOC_ARRAY(writer->to_pack->in_pack_pos, writer->to_pack->nr_objects); 131 132 for (i = 0; i < writer->to_pack->nr_objects; ++i) { 133 struct object_entry *entry = (struct object_entry *)index[i]; 134 enum object_type real_type; 135 136 oe_set_in_pack_pos(writer->to_pack, entry, i); 137 138 switch (oe_type(entry)) { 139 case OBJ_COMMIT: 140 case OBJ_TREE: 141 case OBJ_BLOB: 142 case OBJ_TAG: 143 real_type = oe_type(entry); 144 break; 145 146 default: 147 real_type = odb_read_object_info(writer->to_pack->repo->objects, 148 &entry->idx.oid, NULL); 149 break; 150 } 151 152 switch (real_type) { 153 case OBJ_COMMIT: 154 ewah_set(writer->commits, i + base_objects); 155 break; 156 157 case OBJ_TREE: 158 ewah_set(writer->trees, i + base_objects); 159 break; 160 161 case OBJ_BLOB: 162 ewah_set(writer->blobs, i + base_objects); 163 break; 164 165 case OBJ_TAG: 166 ewah_set(writer->tags, i + base_objects); 167 break; 168 169 default: 170 die("Missing type information for %s (%d/%d)", 171 oid_to_hex(&entry->idx.oid), real_type, 172 oe_type(entry)); 173 } 174 } 175} 176 177int bitmap_writer_has_bitmapped_object_id(struct bitmap_writer *writer, 178 const struct object_id *oid) 179{ 180 return kh_get_oid_map(writer->bitmaps, *oid) != kh_end(writer->bitmaps); 181} 182 183/** 184 * Compute the actual bitmaps 185 */ 186 187void bitmap_writer_push_commit(struct bitmap_writer *writer, 188 struct commit *commit, unsigned pseudo_merge) 189{ 190 if (writer->selected_nr >= writer->selected_alloc) { 191 writer->selected_alloc = (writer->selected_alloc + 32) * 2; 192 REALLOC_ARRAY(writer->selected, writer->selected_alloc); 193 } 194 195 if (!pseudo_merge) { 196 int hash_ret; 197 khiter_t hash_pos = kh_put_oid_map(writer->bitmaps, 198 commit->object.oid, 199 &hash_ret); 200 201 if (!hash_ret) 202 die(_("duplicate entry when writing bitmap index: %s"), 203 oid_to_hex(&commit->object.oid)); 204 kh_value(writer->bitmaps, hash_pos) = NULL; 205 } 206 207 writer->selected[writer->selected_nr].commit = commit; 208 writer->selected[writer->selected_nr].bitmap = NULL; 209 writer->selected[writer->selected_nr].write_as = NULL; 210 writer->selected[writer->selected_nr].flags = 0; 211 writer->selected[writer->selected_nr].pseudo_merge = pseudo_merge; 212 213 writer->selected_nr++; 214} 215 216static uint32_t find_object_pos(struct bitmap_writer *writer, 217 const struct object_id *oid, int *found) 218{ 219 struct object_entry *entry; 220 221 entry = packlist_find(writer->to_pack, oid); 222 if (entry) { 223 uint32_t base_objects = 0; 224 if (writer->midx) 225 base_objects = writer->midx->num_objects + 226 writer->midx->num_objects_in_base; 227 228 if (found) 229 *found = 1; 230 return oe_in_pack_pos(writer->to_pack, entry) + base_objects; 231 } else if (writer->midx) { 232 uint32_t at, pos; 233 234 if (!bsearch_midx(oid, writer->midx, &at)) 235 goto missing; 236 if (midx_to_pack_pos(writer->midx, at, &pos) < 0) 237 goto missing; 238 239 if (found) 240 *found = 1; 241 return pos; 242 } 243 244missing: 245 if (found) 246 *found = 0; 247 warning("Failed to write bitmap index. Packfile doesn't have full closure " 248 "(object %s is missing)", oid_to_hex(oid)); 249 return 0; 250} 251 252static void compute_xor_offsets(struct bitmap_writer *writer) 253{ 254 static const int MAX_XOR_OFFSET_SEARCH = 10; 255 256 int i, next = 0; 257 258 while (next < writer->selected_nr) { 259 struct bitmapped_commit *stored = &writer->selected[next]; 260 int best_offset = 0; 261 struct ewah_bitmap *best_bitmap = stored->bitmap; 262 struct ewah_bitmap *test_xor; 263 264 if (stored->pseudo_merge) 265 goto next; 266 267 for (i = 1; i <= MAX_XOR_OFFSET_SEARCH; ++i) { 268 int curr = next - i; 269 270 if (curr < 0) 271 break; 272 if (writer->selected[curr].pseudo_merge) 273 continue; 274 275 test_xor = ewah_pool_new(); 276 ewah_xor(writer->selected[curr].bitmap, stored->bitmap, test_xor); 277 278 if (test_xor->buffer_size < best_bitmap->buffer_size) { 279 if (best_bitmap != stored->bitmap) 280 ewah_pool_free(best_bitmap); 281 282 best_bitmap = test_xor; 283 best_offset = i; 284 } else { 285 ewah_pool_free(test_xor); 286 } 287 } 288 289next: 290 stored->xor_offset = best_offset; 291 stored->write_as = best_bitmap; 292 293 next++; 294 } 295} 296 297struct bb_commit { 298 struct commit_list *reverse_edges; 299 struct bitmap *commit_mask; 300 struct bitmap *bitmap; 301 unsigned selected:1, 302 maximal:1, 303 pseudo_merge:1; 304 unsigned idx; /* within selected array */ 305}; 306 307static void clear_bb_commit(struct bb_commit *commit) 308{ 309 free_commit_list(commit->reverse_edges); 310 bitmap_free(commit->commit_mask); 311 bitmap_free(commit->bitmap); 312} 313 314define_commit_slab(bb_data, struct bb_commit); 315 316struct bitmap_builder { 317 struct bb_data data; 318 struct commit **commits; 319 size_t commits_nr, commits_alloc; 320}; 321 322static void bitmap_builder_init(struct bitmap_builder *bb, 323 struct bitmap_writer *writer, 324 struct bitmap_index *old_bitmap) 325{ 326 struct rev_info revs; 327 struct commit *commit; 328 struct commit_list *reusable = NULL; 329 struct commit_list *r; 330 unsigned int i, num_maximal = 0; 331 332 memset(bb, 0, sizeof(*bb)); 333 init_bb_data(&bb->data); 334 335 reset_revision_walk(); 336 repo_init_revisions(writer->to_pack->repo, &revs, NULL); 337 revs.topo_order = 1; 338 revs.first_parent_only = 1; 339 340 for (i = 0; i < writer->selected_nr; i++) { 341 struct bitmapped_commit *bc = &writer->selected[i]; 342 struct bb_commit *ent = bb_data_at(&bb->data, bc->commit); 343 344 ent->selected = 1; 345 ent->maximal = 1; 346 ent->pseudo_merge = bc->pseudo_merge; 347 ent->idx = i; 348 349 ent->commit_mask = bitmap_new(); 350 bitmap_set(ent->commit_mask, i); 351 352 add_pending_object(&revs, &bc->commit->object, ""); 353 } 354 355 if (prepare_revision_walk(&revs)) 356 die("revision walk setup failed"); 357 358 while ((commit = get_revision(&revs))) { 359 struct commit_list *p = commit->parents; 360 struct bb_commit *c_ent; 361 362 parse_commit_or_die(commit); 363 364 c_ent = bb_data_at(&bb->data, commit); 365 366 /* 367 * If there is no commit_mask, there is no reason to iterate 368 * over this commit; it is not selected (if it were, it would 369 * not have a blank commit mask) and all its children have 370 * existing bitmaps (see the comment starting with "This commit 371 * has an existing bitmap" below), so it does not contribute 372 * anything to the final bitmap file or its descendants. 373 */ 374 if (!c_ent->commit_mask) 375 continue; 376 377 if (old_bitmap && bitmap_for_commit(old_bitmap, commit)) { 378 /* 379 * This commit has an existing bitmap, so we can 380 * get its bits immediately without an object 381 * walk. That is, it is reusable as-is and there is no 382 * need to continue walking beyond it. 383 * 384 * Mark it as such and add it to bb->commits separately 385 * to avoid allocating a position in the commit mask. 386 */ 387 commit_list_insert(commit, &reusable); 388 goto next; 389 } 390 391 if (c_ent->maximal) { 392 num_maximal++; 393 ALLOC_GROW(bb->commits, bb->commits_nr + 1, bb->commits_alloc); 394 bb->commits[bb->commits_nr++] = commit; 395 } 396 397 if (p) { 398 struct bb_commit *p_ent = bb_data_at(&bb->data, p->item); 399 int c_not_p, p_not_c; 400 401 if (!p_ent->commit_mask) { 402 p_ent->commit_mask = bitmap_new(); 403 c_not_p = 1; 404 p_not_c = 0; 405 } else { 406 c_not_p = bitmap_is_subset(c_ent->commit_mask, p_ent->commit_mask); 407 p_not_c = bitmap_is_subset(p_ent->commit_mask, c_ent->commit_mask); 408 } 409 410 if (!c_not_p) 411 continue; 412 413 bitmap_or(p_ent->commit_mask, c_ent->commit_mask); 414 415 if (p_not_c) 416 p_ent->maximal = 1; 417 else { 418 p_ent->maximal = 0; 419 free_commit_list(p_ent->reverse_edges); 420 p_ent->reverse_edges = NULL; 421 } 422 423 if (c_ent->maximal) { 424 commit_list_insert(commit, &p_ent->reverse_edges); 425 } else { 426 struct commit_list *cc = c_ent->reverse_edges; 427 428 for (; cc; cc = cc->next) { 429 if (!commit_list_contains(cc->item, p_ent->reverse_edges)) 430 commit_list_insert(cc->item, &p_ent->reverse_edges); 431 } 432 } 433 } 434 435next: 436 bitmap_free(c_ent->commit_mask); 437 c_ent->commit_mask = NULL; 438 } 439 440 for (r = reusable; r; r = r->next) { 441 ALLOC_GROW(bb->commits, bb->commits_nr + 1, bb->commits_alloc); 442 bb->commits[bb->commits_nr++] = r->item; 443 } 444 445 trace2_data_intmax("pack-bitmap-write", writer->repo, 446 "num_selected_commits", writer->selected_nr); 447 trace2_data_intmax("pack-bitmap-write", writer->repo, 448 "num_maximal_commits", num_maximal); 449 450 release_revisions(&revs); 451 free_commit_list(reusable); 452} 453 454static void bitmap_builder_clear(struct bitmap_builder *bb) 455{ 456 deep_clear_bb_data(&bb->data, clear_bb_commit); 457 free(bb->commits); 458 bb->commits_nr = bb->commits_alloc = 0; 459} 460 461static int fill_bitmap_tree(struct bitmap_writer *writer, 462 struct bitmap *bitmap, 463 struct tree *tree) 464{ 465 int found; 466 uint32_t pos; 467 struct tree_desc desc; 468 struct name_entry entry; 469 470 /* 471 * If our bit is already set, then there is nothing to do. Both this 472 * tree and all of its children will be set. 473 */ 474 pos = find_object_pos(writer, &tree->object.oid, &found); 475 if (!found) 476 return -1; 477 if (bitmap_get(bitmap, pos)) 478 return 0; 479 bitmap_set(bitmap, pos); 480 481 if (parse_tree(tree) < 0) 482 die("unable to load tree object %s", 483 oid_to_hex(&tree->object.oid)); 484 init_tree_desc(&desc, &tree->object.oid, tree->buffer, tree->size); 485 486 while (tree_entry(&desc, &entry)) { 487 switch (object_type(entry.mode)) { 488 case OBJ_TREE: 489 if (fill_bitmap_tree(writer, bitmap, 490 lookup_tree(writer->repo, &entry.oid)) < 0) 491 return -1; 492 break; 493 case OBJ_BLOB: 494 pos = find_object_pos(writer, &entry.oid, &found); 495 if (!found) 496 return -1; 497 bitmap_set(bitmap, pos); 498 break; 499 default: 500 /* Gitlink, etc; not reachable */ 501 break; 502 } 503 } 504 505 free_tree_buffer(tree); 506 return 0; 507} 508 509static int reused_bitmaps_nr; 510static int reused_pseudo_merge_bitmaps_nr; 511 512static int fill_bitmap_commit(struct bitmap_writer *writer, 513 struct bb_commit *ent, 514 struct commit *commit, 515 struct prio_queue *queue, 516 struct prio_queue *tree_queue, 517 struct bitmap_index *old_bitmap, 518 const uint32_t *mapping) 519{ 520 int found; 521 uint32_t pos; 522 if (!ent->bitmap) 523 ent->bitmap = bitmap_new(); 524 525 prio_queue_put(queue, commit); 526 527 while (queue->nr) { 528 struct commit_list *p; 529 struct commit *c = prio_queue_get(queue); 530 531 if (old_bitmap && mapping) { 532 struct ewah_bitmap *old; 533 struct bitmap *remapped = bitmap_new(); 534 535 if (commit->object.flags & BITMAP_PSEUDO_MERGE) 536 old = pseudo_merge_bitmap_for_commit(old_bitmap, c); 537 else 538 old = bitmap_for_commit(old_bitmap, c); 539 /* 540 * If this commit has an old bitmap, then translate that 541 * bitmap and add its bits to this one. No need to walk 542 * parents or the tree for this commit. 543 */ 544 if (old && !rebuild_bitmap(mapping, old, remapped)) { 545 bitmap_or(ent->bitmap, remapped); 546 bitmap_free(remapped); 547 if (commit->object.flags & BITMAP_PSEUDO_MERGE) 548 reused_pseudo_merge_bitmaps_nr++; 549 else 550 reused_bitmaps_nr++; 551 continue; 552 } 553 bitmap_free(remapped); 554 } 555 556 /* 557 * Mark ourselves and queue our tree. The commit 558 * walk ensures we cover all parents. 559 */ 560 if (!(c->object.flags & BITMAP_PSEUDO_MERGE)) { 561 pos = find_object_pos(writer, &c->object.oid, &found); 562 if (!found) 563 return -1; 564 bitmap_set(ent->bitmap, pos); 565 prio_queue_put(tree_queue, 566 repo_get_commit_tree(writer->repo, c)); 567 } 568 569 for (p = c->parents; p; p = p->next) { 570 pos = find_object_pos(writer, &p->item->object.oid, 571 &found); 572 if (!found) 573 return -1; 574 if (!bitmap_get(ent->bitmap, pos)) { 575 bitmap_set(ent->bitmap, pos); 576 prio_queue_put(queue, p->item); 577 } 578 } 579 } 580 581 while (tree_queue->nr) { 582 if (fill_bitmap_tree(writer, ent->bitmap, 583 prio_queue_get(tree_queue)) < 0) 584 return -1; 585 } 586 return 0; 587} 588 589static void store_selected(struct bitmap_writer *writer, 590 struct bb_commit *ent, struct commit *commit) 591{ 592 struct bitmapped_commit *stored = &writer->selected[ent->idx]; 593 khiter_t hash_pos; 594 595 stored->bitmap = bitmap_to_ewah(ent->bitmap); 596 597 if (ent->pseudo_merge) 598 return; 599 600 hash_pos = kh_get_oid_map(writer->bitmaps, commit->object.oid); 601 if (hash_pos == kh_end(writer->bitmaps)) 602 die(_("attempted to store non-selected commit: '%s'"), 603 oid_to_hex(&commit->object.oid)); 604 605 kh_value(writer->bitmaps, hash_pos) = stored; 606} 607 608int bitmap_writer_build(struct bitmap_writer *writer) 609{ 610 struct bitmap_builder bb; 611 size_t i; 612 int nr_stored = 0; /* for progress */ 613 struct prio_queue queue = { compare_commits_by_gen_then_commit_date }; 614 struct prio_queue tree_queue = { NULL }; 615 struct bitmap_index *old_bitmap; 616 uint32_t *mapping = NULL; 617 int closed = 1; /* until proven otherwise */ 618 619 if (writer->show_progress) 620 writer->progress = start_progress(writer->repo, 621 "Building bitmaps", 622 writer->selected_nr); 623 trace2_region_enter("pack-bitmap-write", "building_bitmaps_total", 624 writer->repo); 625 626 old_bitmap = prepare_bitmap_git(writer->to_pack->repo); 627 if (old_bitmap) 628 mapping = create_bitmap_mapping(old_bitmap, writer->to_pack); 629 else 630 mapping = NULL; 631 632 bitmap_builder_init(&bb, writer, old_bitmap); 633 for (i = bb.commits_nr; i > 0; i--) { 634 struct commit *commit = bb.commits[i-1]; 635 struct bb_commit *ent = bb_data_at(&bb.data, commit); 636 struct commit *child; 637 int reused = 0; 638 639 if (fill_bitmap_commit(writer, ent, commit, &queue, &tree_queue, 640 old_bitmap, mapping) < 0) { 641 closed = 0; 642 break; 643 } 644 645 if (ent->selected) { 646 store_selected(writer, ent, commit); 647 nr_stored++; 648 display_progress(writer->progress, nr_stored); 649 } 650 651 while ((child = pop_commit(&ent->reverse_edges))) { 652 struct bb_commit *child_ent = 653 bb_data_at(&bb.data, child); 654 655 if (child_ent->bitmap) 656 bitmap_or(child_ent->bitmap, ent->bitmap); 657 else if (reused) 658 child_ent->bitmap = bitmap_dup(ent->bitmap); 659 else { 660 child_ent->bitmap = ent->bitmap; 661 reused = 1; 662 } 663 } 664 if (!reused) 665 bitmap_free(ent->bitmap); 666 ent->bitmap = NULL; 667 } 668 clear_prio_queue(&queue); 669 clear_prio_queue(&tree_queue); 670 bitmap_builder_clear(&bb); 671 free_bitmap_index(old_bitmap); 672 free(mapping); 673 674 trace2_region_leave("pack-bitmap-write", "building_bitmaps_total", 675 writer->repo); 676 trace2_data_intmax("pack-bitmap-write", writer->repo, 677 "building_bitmaps_reused", reused_bitmaps_nr); 678 trace2_data_intmax("pack-bitmap-write", writer->repo, 679 "building_bitmaps_pseudo_merge_reused", 680 reused_pseudo_merge_bitmaps_nr); 681 682 stop_progress(&writer->progress); 683 684 if (closed) 685 compute_xor_offsets(writer); 686 return closed ? 0 : -1; 687} 688 689/** 690 * Select the commits that will be bitmapped 691 */ 692static inline unsigned int next_commit_index(unsigned int idx) 693{ 694 static const unsigned int MIN_COMMITS = 100; 695 static const unsigned int MAX_COMMITS = 5000; 696 697 static const unsigned int MUST_REGION = 100; 698 static const unsigned int MIN_REGION = 20000; 699 700 unsigned int offset, next; 701 702 if (idx <= MUST_REGION) 703 return 0; 704 705 if (idx <= MIN_REGION) { 706 offset = idx - MUST_REGION; 707 return (offset < MIN_COMMITS) ? offset : MIN_COMMITS; 708 } 709 710 offset = idx - MIN_REGION; 711 next = (offset < MAX_COMMITS) ? offset : MAX_COMMITS; 712 713 return (next > MIN_COMMITS) ? next : MIN_COMMITS; 714} 715 716static int date_compare(const void *_a, const void *_b) 717{ 718 struct commit *a = *(struct commit **)_a; 719 struct commit *b = *(struct commit **)_b; 720 return (long)b->date - (long)a->date; 721} 722 723void bitmap_writer_select_commits(struct bitmap_writer *writer, 724 struct commit **indexed_commits, 725 unsigned int indexed_commits_nr) 726{ 727 unsigned int i = 0, j, next; 728 729 QSORT(indexed_commits, indexed_commits_nr, date_compare); 730 731 if (indexed_commits_nr < 100) { 732 for (i = 0; i < indexed_commits_nr; ++i) 733 bitmap_writer_push_commit(writer, indexed_commits[i], 0); 734 735 select_pseudo_merges(writer); 736 737 return; 738 } 739 740 if (writer->show_progress) 741 writer->progress = start_progress(writer->repo, 742 "Selecting bitmap commits", 0); 743 744 for (;;) { 745 struct commit *chosen = NULL; 746 747 next = next_commit_index(i); 748 749 if (i + next >= indexed_commits_nr) 750 break; 751 752 if (next == 0) { 753 chosen = indexed_commits[i]; 754 } else { 755 chosen = indexed_commits[i + next]; 756 757 for (j = 0; j <= next; ++j) { 758 struct commit *cm = indexed_commits[i + j]; 759 760 if ((cm->object.flags & NEEDS_BITMAP) != 0) { 761 chosen = cm; 762 break; 763 } 764 765 if (cm->parents && cm->parents->next) 766 chosen = cm; 767 } 768 } 769 770 bitmap_writer_push_commit(writer, chosen, 0); 771 772 i += next + 1; 773 display_progress(writer->progress, i); 774 } 775 776 stop_progress(&writer->progress); 777 778 select_pseudo_merges(writer); 779} 780 781 782static int hashwrite_ewah_helper(void *f, const void *buf, size_t len) 783{ 784 /* hashwrite will die on error */ 785 hashwrite(f, buf, len); 786 return len; 787} 788 789/** 790 * Write the bitmap index to disk 791 */ 792static inline void dump_bitmap(struct hashfile *f, struct ewah_bitmap *bitmap) 793{ 794 if (ewah_serialize_to(bitmap, hashwrite_ewah_helper, f) < 0) 795 die("Failed to write bitmap index"); 796} 797 798static const struct object_id *oid_access(size_t pos, const void *table) 799{ 800 const struct pack_idx_entry * const *index = table; 801 return &index[pos]->oid; 802} 803 804static void write_selected_commits_v1(struct bitmap_writer *writer, 805 struct hashfile *f, off_t *offsets) 806{ 807 int i; 808 809 for (i = 0; i < bitmap_writer_nr_selected_commits(writer); ++i) { 810 struct bitmapped_commit *stored = &writer->selected[i]; 811 if (stored->pseudo_merge) 812 BUG("unexpected pseudo-merge among selected: %s", 813 oid_to_hex(&stored->commit->object.oid)); 814 815 if (offsets) 816 offsets[i] = hashfile_total(f); 817 818 hashwrite_be32(f, stored->commit_pos); 819 hashwrite_u8(f, stored->xor_offset); 820 hashwrite_u8(f, stored->flags); 821 822 dump_bitmap(f, stored->write_as); 823 } 824} 825 826static void write_pseudo_merges(struct bitmap_writer *writer, 827 struct hashfile *f) 828{ 829 struct oid_array commits = OID_ARRAY_INIT; 830 struct bitmap **commits_bitmap = NULL; 831 off_t *pseudo_merge_ofs = NULL; 832 off_t start, table_start, next_ext; 833 834 uint32_t base = bitmap_writer_nr_selected_commits(writer); 835 size_t i, j = 0; 836 837 CALLOC_ARRAY(commits_bitmap, writer->pseudo_merges_nr); 838 CALLOC_ARRAY(pseudo_merge_ofs, writer->pseudo_merges_nr); 839 840 for (i = 0; i < writer->pseudo_merges_nr; i++) { 841 struct bitmapped_commit *merge = &writer->selected[base + i]; 842 struct commit_list *p; 843 844 if (!merge->pseudo_merge) 845 BUG("found non-pseudo merge commit at %"PRIuMAX, (uintmax_t)i); 846 847 commits_bitmap[i] = bitmap_new(); 848 849 for (p = merge->commit->parents; p; p = p->next) 850 bitmap_set(commits_bitmap[i], 851 find_object_pos(writer, &p->item->object.oid, 852 NULL)); 853 } 854 855 start = hashfile_total(f); 856 857 for (i = 0; i < writer->pseudo_merges_nr; i++) { 858 struct ewah_bitmap *commits_ewah = bitmap_to_ewah(commits_bitmap[i]); 859 860 pseudo_merge_ofs[i] = hashfile_total(f); 861 862 dump_bitmap(f, commits_ewah); 863 dump_bitmap(f, writer->selected[base+i].write_as); 864 865 ewah_free(commits_ewah); 866 } 867 868 next_ext = st_add(hashfile_total(f), 869 st_mult(kh_size(writer->pseudo_merge_commits), 870 sizeof(uint64_t))); 871 872 table_start = hashfile_total(f); 873 874 commits.alloc = kh_size(writer->pseudo_merge_commits); 875 CALLOC_ARRAY(commits.oid, commits.alloc); 876 877 for (i = kh_begin(writer->pseudo_merge_commits); i != kh_end(writer->pseudo_merge_commits); i++) { 878 if (!kh_exist(writer->pseudo_merge_commits, i)) 879 continue; 880 oid_array_append(&commits, &kh_key(writer->pseudo_merge_commits, i)); 881 } 882 883 oid_array_sort(&commits); 884 885 /* write lookup table (non-extended) */ 886 for (i = 0; i < commits.nr; i++) { 887 int hash_pos; 888 struct pseudo_merge_commit_idx *c; 889 890 hash_pos = kh_get_oid_map(writer->pseudo_merge_commits, 891 commits.oid[i]); 892 if (hash_pos == kh_end(writer->pseudo_merge_commits)) 893 BUG("could not find pseudo-merge commit %s", 894 oid_to_hex(&commits.oid[i])); 895 896 c = kh_value(writer->pseudo_merge_commits, hash_pos); 897 898 hashwrite_be32(f, find_object_pos(writer, &commits.oid[i], 899 NULL)); 900 if (c->nr == 1) 901 hashwrite_be64(f, pseudo_merge_ofs[c->pseudo_merge[0]]); 902 else if (c->nr > 1) { 903 if (next_ext & ((uint64_t)1<<63)) 904 die(_("too many pseudo-merges")); 905 hashwrite_be64(f, next_ext | ((uint64_t)1<<63)); 906 next_ext = st_add3(next_ext, 907 sizeof(uint32_t), 908 st_mult(c->nr, sizeof(uint64_t))); 909 } else 910 BUG("expected commit '%s' to have at least one " 911 "pseudo-merge", oid_to_hex(&commits.oid[i])); 912 } 913 914 /* write lookup table (extended) */ 915 for (i = 0; i < commits.nr; i++) { 916 int hash_pos; 917 struct pseudo_merge_commit_idx *c; 918 919 hash_pos = kh_get_oid_map(writer->pseudo_merge_commits, 920 commits.oid[i]); 921 if (hash_pos == kh_end(writer->pseudo_merge_commits)) 922 BUG("could not find pseudo-merge commit %s", 923 oid_to_hex(&commits.oid[i])); 924 925 c = kh_value(writer->pseudo_merge_commits, hash_pos); 926 if (c->nr == 1) 927 continue; 928 929 hashwrite_be32(f, c->nr); 930 for (j = 0; j < c->nr; j++) 931 hashwrite_be64(f, pseudo_merge_ofs[c->pseudo_merge[j]]); 932 } 933 934 /* write positions for all pseudo merges */ 935 for (i = 0; i < writer->pseudo_merges_nr; i++) 936 hashwrite_be64(f, pseudo_merge_ofs[i]); 937 938 hashwrite_be32(f, writer->pseudo_merges_nr); 939 hashwrite_be32(f, kh_size(writer->pseudo_merge_commits)); 940 hashwrite_be64(f, table_start - start); 941 hashwrite_be64(f, hashfile_total(f) - start + sizeof(uint64_t)); 942 943 for (i = 0; i < writer->pseudo_merges_nr; i++) 944 bitmap_free(commits_bitmap[i]); 945 946 oid_array_clear(&commits); 947 free(pseudo_merge_ofs); 948 free(commits_bitmap); 949} 950 951static int table_cmp(const void *_va, const void *_vb, void *_data) 952{ 953 struct bitmap_writer *writer = _data; 954 struct bitmapped_commit *a = &writer->selected[*(uint32_t *)_va]; 955 struct bitmapped_commit *b = &writer->selected[*(uint32_t *)_vb]; 956 957 if (a->commit_pos < b->commit_pos) 958 return -1; 959 else if (a->commit_pos > b->commit_pos) 960 return 1; 961 962 return 0; 963} 964 965static void write_lookup_table(struct bitmap_writer *writer, struct hashfile *f, 966 off_t *offsets) 967{ 968 uint32_t i; 969 uint32_t *table, *table_inv; 970 971 ALLOC_ARRAY(table, bitmap_writer_nr_selected_commits(writer)); 972 ALLOC_ARRAY(table_inv, bitmap_writer_nr_selected_commits(writer)); 973 974 for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++) 975 table[i] = i; 976 977 /* 978 * At the end of this sort table[j] = i means that the i'th 979 * bitmap corresponds to j'th bitmapped commit (among the selected 980 * commits) in lex order of OIDs. 981 */ 982 QSORT_S(table, bitmap_writer_nr_selected_commits(writer), table_cmp, writer); 983 984 /* table_inv helps us discover that relationship (i'th bitmap 985 * to j'th commit by j = table_inv[i]) 986 */ 987 for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++) 988 table_inv[table[i]] = i; 989 990 trace2_region_enter("pack-bitmap-write", "writing_lookup_table", writer->repo); 991 for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++) { 992 struct bitmapped_commit *selected = &writer->selected[table[i]]; 993 uint32_t xor_offset = selected->xor_offset; 994 uint32_t xor_row; 995 996 if (xor_offset) { 997 /* 998 * xor_index stores the index (in the bitmap entries) 999 * of the corresponding xor bitmap. But we need to convert 1000 * this index into lookup table's index. So, table_inv[xor_index] 1001 * gives us the index position w.r.t. the lookup table. 1002 * 1003 * If "k = table[i] - xor_offset" then the xor base is the k'th 1004 * bitmap. `table_inv[k]` gives us the position of that bitmap 1005 * in the lookup table. 1006 */ 1007 uint32_t xor_index = table[i] - xor_offset; 1008 xor_row = table_inv[xor_index]; 1009 } else { 1010 xor_row = 0xffffffff; 1011 } 1012 1013 hashwrite_be32(f, writer->selected[table[i]].commit_pos); 1014 hashwrite_be64(f, (uint64_t)offsets[table[i]]); 1015 hashwrite_be32(f, xor_row); 1016 } 1017 trace2_region_leave("pack-bitmap-write", "writing_lookup_table", writer->repo); 1018 1019 free(table); 1020 free(table_inv); 1021} 1022 1023static void write_hash_cache(struct hashfile *f, 1024 struct pack_idx_entry **index, 1025 uint32_t index_nr) 1026{ 1027 uint32_t i; 1028 1029 for (i = 0; i < index_nr; ++i) { 1030 struct object_entry *entry = (struct object_entry *)index[i]; 1031 hashwrite_be32(f, entry->hash); 1032 } 1033} 1034 1035void bitmap_writer_set_checksum(struct bitmap_writer *writer, 1036 const unsigned char *sha1) 1037{ 1038 hashcpy(writer->pack_checksum, sha1, writer->repo->hash_algo); 1039} 1040 1041void bitmap_writer_finish(struct bitmap_writer *writer, 1042 struct pack_idx_entry **index, 1043 const char *filename, 1044 uint16_t options) 1045{ 1046 static uint16_t default_version = 1; 1047 static uint16_t flags = BITMAP_OPT_FULL_DAG; 1048 struct strbuf tmp_file = STRBUF_INIT; 1049 struct hashfile *f; 1050 off_t *offsets = NULL; 1051 uint32_t i, base_objects; 1052 1053 struct bitmap_disk_header header; 1054 1055 int fd = odb_mkstemp(writer->repo->objects, &tmp_file, 1056 "pack/tmp_bitmap_XXXXXX"); 1057 1058 if (writer->pseudo_merges_nr) 1059 options |= BITMAP_OPT_PSEUDO_MERGES; 1060 1061 f = hashfd(writer->repo->hash_algo, fd, tmp_file.buf); 1062 1063 memcpy(header.magic, BITMAP_IDX_SIGNATURE, sizeof(BITMAP_IDX_SIGNATURE)); 1064 header.version = htons(default_version); 1065 header.options = htons(flags | options); 1066 header.entry_count = htonl(bitmap_writer_nr_selected_commits(writer)); 1067 hashcpy(header.checksum, writer->pack_checksum, writer->repo->hash_algo); 1068 1069 hashwrite(f, &header, sizeof(header) - GIT_MAX_RAWSZ + writer->repo->hash_algo->rawsz); 1070 dump_bitmap(f, writer->commits); 1071 dump_bitmap(f, writer->trees); 1072 dump_bitmap(f, writer->blobs); 1073 dump_bitmap(f, writer->tags); 1074 1075 if (options & BITMAP_OPT_LOOKUP_TABLE) 1076 CALLOC_ARRAY(offsets, writer->to_pack->nr_objects); 1077 1078 if (writer->midx) 1079 base_objects = writer->midx->num_objects + 1080 writer->midx->num_objects_in_base; 1081 else 1082 base_objects = 0; 1083 1084 for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++) { 1085 struct bitmapped_commit *stored = &writer->selected[i]; 1086 int commit_pos = oid_pos(&stored->commit->object.oid, index, 1087 writer->to_pack->nr_objects, 1088 oid_access); 1089 1090 if (commit_pos < 0) 1091 BUG("trying to write commit not in index"); 1092 stored->commit_pos = commit_pos + base_objects; 1093 } 1094 1095 write_selected_commits_v1(writer, f, offsets); 1096 1097 if (options & BITMAP_OPT_PSEUDO_MERGES) 1098 write_pseudo_merges(writer, f); 1099 1100 if (options & BITMAP_OPT_LOOKUP_TABLE) 1101 write_lookup_table(writer, f, offsets); 1102 1103 if (options & BITMAP_OPT_HASH_CACHE) 1104 write_hash_cache(f, index, writer->to_pack->nr_objects); 1105 1106 finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA, 1107 CSUM_HASH_IN_STREAM | CSUM_FSYNC | CSUM_CLOSE); 1108 1109 if (adjust_shared_perm(writer->repo, tmp_file.buf)) 1110 die_errno("unable to make temporary bitmap file readable"); 1111 1112 if (rename(tmp_file.buf, filename)) 1113 die_errno("unable to rename temporary bitmap file to '%s'", filename); 1114 1115 strbuf_release(&tmp_file); 1116 free(offsets); 1117}