git

Форк
0
/
pack-bitmap-write.c 
1071 строка · 27.3 Кб
1
#define USE_THE_REPOSITORY_VARIABLE
2

3
#include "git-compat-util.h"
4
#include "environment.h"
5
#include "gettext.h"
6
#include "hex.h"
7
#include "object-store-ll.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

29
struct bitmapped_commit {
30
	struct commit *commit;
31
	struct ewah_bitmap *bitmap;
32
	struct ewah_bitmap *write_as;
33
	int flags;
34
	int xor_offset;
35
	uint32_t commit_pos;
36
	unsigned pseudo_merge : 1;
37
};
38

39
static inline int bitmap_writer_nr_selected_commits(struct bitmap_writer *writer)
40
{
41
	return writer->selected_nr - writer->pseudo_merges_nr;
42
}
43

44
void bitmap_writer_init(struct bitmap_writer *writer, struct repository *r,
45
			struct packing_data *pdata)
46
{
47
	memset(writer, 0, sizeof(struct bitmap_writer));
48
	if (writer->bitmaps)
49
		BUG("bitmap writer already initialized");
50
	writer->bitmaps = kh_init_oid_map();
51
	writer->pseudo_merge_commits = kh_init_oid_map();
52
	writer->to_pack = pdata;
53

54
	string_list_init_dup(&writer->pseudo_merge_groups);
55

56
	load_pseudo_merges_from_config(r, &writer->pseudo_merge_groups);
57
}
58

59
static void free_pseudo_merge_commit_idx(struct pseudo_merge_commit_idx *idx)
60
{
61
	if (!idx)
62
		return;
63
	free(idx->pseudo_merge);
64
	free(idx);
65
}
66

67
void bitmap_writer_free(struct bitmap_writer *writer)
68
{
69
	uint32_t i;
70
	struct pseudo_merge_commit_idx *idx;
71

72
	if (!writer)
73
		return;
74

75
	ewah_free(writer->commits);
76
	ewah_free(writer->trees);
77
	ewah_free(writer->blobs);
78
	ewah_free(writer->tags);
79

80
	kh_destroy_oid_map(writer->bitmaps);
81

82
	kh_foreach_value(writer->pseudo_merge_commits, idx,
83
			 free_pseudo_merge_commit_idx(idx));
84
	kh_destroy_oid_map(writer->pseudo_merge_commits);
85

86
	for (i = 0; i < writer->selected_nr; i++) {
87
		struct bitmapped_commit *bc = &writer->selected[i];
88
		if (bc->write_as != bc->bitmap)
89
			ewah_free(bc->write_as);
90
		ewah_free(bc->bitmap);
91
	}
92
	free(writer->selected);
93
}
94

95
void bitmap_writer_show_progress(struct bitmap_writer *writer, int show)
96
{
97
	writer->show_progress = show;
98
}
99

100
/**
101
 * Build the initial type index for the packfile or multi-pack-index
102
 */
103
void bitmap_writer_build_type_index(struct bitmap_writer *writer,
104
				    struct pack_idx_entry **index)
105
{
106
	uint32_t i;
107

108
	writer->commits = ewah_new();
109
	writer->trees = ewah_new();
110
	writer->blobs = ewah_new();
111
	writer->tags = ewah_new();
112
	ALLOC_ARRAY(writer->to_pack->in_pack_pos, writer->to_pack->nr_objects);
113

114
	for (i = 0; i < writer->to_pack->nr_objects; ++i) {
115
		struct object_entry *entry = (struct object_entry *)index[i];
116
		enum object_type real_type;
117

118
		oe_set_in_pack_pos(writer->to_pack, entry, i);
119

120
		switch (oe_type(entry)) {
121
		case OBJ_COMMIT:
122
		case OBJ_TREE:
123
		case OBJ_BLOB:
124
		case OBJ_TAG:
125
			real_type = oe_type(entry);
126
			break;
127

128
		default:
129
			real_type = oid_object_info(writer->to_pack->repo,
130
						    &entry->idx.oid, NULL);
131
			break;
132
		}
133

134
		switch (real_type) {
135
		case OBJ_COMMIT:
136
			ewah_set(writer->commits, i);
137
			break;
138

139
		case OBJ_TREE:
140
			ewah_set(writer->trees, i);
141
			break;
142

143
		case OBJ_BLOB:
144
			ewah_set(writer->blobs, i);
145
			break;
146

147
		case OBJ_TAG:
148
			ewah_set(writer->tags, i);
149
			break;
150

151
		default:
152
			die("Missing type information for %s (%d/%d)",
153
			    oid_to_hex(&entry->idx.oid), real_type,
154
			    oe_type(entry));
155
		}
156
	}
157
}
158

159
int bitmap_writer_has_bitmapped_object_id(struct bitmap_writer *writer,
160
					  const struct object_id *oid)
161
{
162
	return kh_get_oid_map(writer->bitmaps, *oid) != kh_end(writer->bitmaps);
163
}
164

165
/**
166
 * Compute the actual bitmaps
167
 */
168

169
void bitmap_writer_push_commit(struct bitmap_writer *writer,
170
			       struct commit *commit, unsigned pseudo_merge)
171
{
172
	if (writer->selected_nr >= writer->selected_alloc) {
173
		writer->selected_alloc = (writer->selected_alloc + 32) * 2;
174
		REALLOC_ARRAY(writer->selected, writer->selected_alloc);
175
	}
176

177
	if (!pseudo_merge) {
178
		int hash_ret;
179
		khiter_t hash_pos = kh_put_oid_map(writer->bitmaps,
180
						   commit->object.oid,
181
						   &hash_ret);
182

183
		if (!hash_ret)
184
			die(_("duplicate entry when writing bitmap index: %s"),
185
			    oid_to_hex(&commit->object.oid));
186
		kh_value(writer->bitmaps, hash_pos) = NULL;
187
	}
188

189
	writer->selected[writer->selected_nr].commit = commit;
190
	writer->selected[writer->selected_nr].bitmap = NULL;
191
	writer->selected[writer->selected_nr].write_as = NULL;
192
	writer->selected[writer->selected_nr].flags = 0;
193
	writer->selected[writer->selected_nr].pseudo_merge = pseudo_merge;
194

195
	writer->selected_nr++;
196
}
197

198
static uint32_t find_object_pos(struct bitmap_writer *writer,
199
				const struct object_id *oid, int *found)
200
{
201
	struct object_entry *entry = packlist_find(writer->to_pack, oid);
202

203
	if (!entry) {
204
		if (found)
205
			*found = 0;
206
		warning("Failed to write bitmap index. Packfile doesn't have full closure "
207
			"(object %s is missing)", oid_to_hex(oid));
208
		return 0;
209
	}
210

211
	if (found)
212
		*found = 1;
213
	return oe_in_pack_pos(writer->to_pack, entry);
214
}
215

216
static void compute_xor_offsets(struct bitmap_writer *writer)
217
{
218
	static const int MAX_XOR_OFFSET_SEARCH = 10;
219

220
	int i, next = 0;
221

222
	while (next < writer->selected_nr) {
223
		struct bitmapped_commit *stored = &writer->selected[next];
224
		int best_offset = 0;
225
		struct ewah_bitmap *best_bitmap = stored->bitmap;
226
		struct ewah_bitmap *test_xor;
227

228
		if (stored->pseudo_merge)
229
			goto next;
230

231
		for (i = 1; i <= MAX_XOR_OFFSET_SEARCH; ++i) {
232
			int curr = next - i;
233

234
			if (curr < 0)
235
				break;
236
			if (writer->selected[curr].pseudo_merge)
237
				continue;
238

239
			test_xor = ewah_pool_new();
240
			ewah_xor(writer->selected[curr].bitmap, stored->bitmap, test_xor);
241

242
			if (test_xor->buffer_size < best_bitmap->buffer_size) {
243
				if (best_bitmap != stored->bitmap)
244
					ewah_pool_free(best_bitmap);
245

246
				best_bitmap = test_xor;
247
				best_offset = i;
248
			} else {
249
				ewah_pool_free(test_xor);
250
			}
251
		}
252

253
next:
254
		stored->xor_offset = best_offset;
255
		stored->write_as = best_bitmap;
256

257
		next++;
258
	}
259
}
260

261
struct bb_commit {
262
	struct commit_list *reverse_edges;
263
	struct bitmap *commit_mask;
264
	struct bitmap *bitmap;
265
	unsigned selected:1,
266
		 maximal:1,
267
		 pseudo_merge:1;
268
	unsigned idx; /* within selected array */
269
};
270

271
static void clear_bb_commit(struct bb_commit *commit)
272
{
273
	free_commit_list(commit->reverse_edges);
274
	bitmap_free(commit->commit_mask);
275
	bitmap_free(commit->bitmap);
276
}
277

278
define_commit_slab(bb_data, struct bb_commit);
279

280
struct bitmap_builder {
281
	struct bb_data data;
282
	struct commit **commits;
283
	size_t commits_nr, commits_alloc;
284
};
285

286
static void bitmap_builder_init(struct bitmap_builder *bb,
287
				struct bitmap_writer *writer,
288
				struct bitmap_index *old_bitmap)
289
{
290
	struct rev_info revs;
291
	struct commit *commit;
292
	struct commit_list *reusable = NULL;
293
	struct commit_list *r;
294
	unsigned int i, num_maximal = 0;
295

296
	memset(bb, 0, sizeof(*bb));
297
	init_bb_data(&bb->data);
298

299
	reset_revision_walk();
300
	repo_init_revisions(writer->to_pack->repo, &revs, NULL);
301
	revs.topo_order = 1;
302
	revs.first_parent_only = 1;
303

304
	for (i = 0; i < writer->selected_nr; i++) {
305
		struct bitmapped_commit *bc = &writer->selected[i];
306
		struct bb_commit *ent = bb_data_at(&bb->data, bc->commit);
307

308
		ent->selected = 1;
309
		ent->maximal = 1;
310
		ent->pseudo_merge = bc->pseudo_merge;
311
		ent->idx = i;
312

313
		ent->commit_mask = bitmap_new();
314
		bitmap_set(ent->commit_mask, i);
315

316
		add_pending_object(&revs, &bc->commit->object, "");
317
	}
318

319
	if (prepare_revision_walk(&revs))
320
		die("revision walk setup failed");
321

322
	while ((commit = get_revision(&revs))) {
323
		struct commit_list *p = commit->parents;
324
		struct bb_commit *c_ent;
325

326
		parse_commit_or_die(commit);
327

328
		c_ent = bb_data_at(&bb->data, commit);
329

330
		/*
331
		 * If there is no commit_mask, there is no reason to iterate
332
		 * over this commit; it is not selected (if it were, it would
333
		 * not have a blank commit mask) and all its children have
334
		 * existing bitmaps (see the comment starting with "This commit
335
		 * has an existing bitmap" below), so it does not contribute
336
		 * anything to the final bitmap file or its descendants.
337
		 */
338
		if (!c_ent->commit_mask)
339
			continue;
340

341
		if (old_bitmap && bitmap_for_commit(old_bitmap, commit)) {
342
			/*
343
			 * This commit has an existing bitmap, so we can
344
			 * get its bits immediately without an object
345
			 * walk. That is, it is reusable as-is and there is no
346
			 * need to continue walking beyond it.
347
			 *
348
			 * Mark it as such and add it to bb->commits separately
349
			 * to avoid allocating a position in the commit mask.
350
			 */
351
			commit_list_insert(commit, &reusable);
352
			goto next;
353
		}
354

355
		if (c_ent->maximal) {
356
			num_maximal++;
357
			ALLOC_GROW(bb->commits, bb->commits_nr + 1, bb->commits_alloc);
358
			bb->commits[bb->commits_nr++] = commit;
359
		}
360

361
		if (p) {
362
			struct bb_commit *p_ent = bb_data_at(&bb->data, p->item);
363
			int c_not_p, p_not_c;
364

365
			if (!p_ent->commit_mask) {
366
				p_ent->commit_mask = bitmap_new();
367
				c_not_p = 1;
368
				p_not_c = 0;
369
			} else {
370
				c_not_p = bitmap_is_subset(c_ent->commit_mask, p_ent->commit_mask);
371
				p_not_c = bitmap_is_subset(p_ent->commit_mask, c_ent->commit_mask);
372
			}
373

374
			if (!c_not_p)
375
				continue;
376

377
			bitmap_or(p_ent->commit_mask, c_ent->commit_mask);
378

379
			if (p_not_c)
380
				p_ent->maximal = 1;
381
			else {
382
				p_ent->maximal = 0;
383
				free_commit_list(p_ent->reverse_edges);
384
				p_ent->reverse_edges = NULL;
385
			}
386

387
			if (c_ent->maximal) {
388
				commit_list_insert(commit, &p_ent->reverse_edges);
389
			} else {
390
				struct commit_list *cc = c_ent->reverse_edges;
391

392
				for (; cc; cc = cc->next) {
393
					if (!commit_list_contains(cc->item, p_ent->reverse_edges))
394
						commit_list_insert(cc->item, &p_ent->reverse_edges);
395
				}
396
			}
397
		}
398

399
next:
400
		bitmap_free(c_ent->commit_mask);
401
		c_ent->commit_mask = NULL;
402
	}
403

404
	for (r = reusable; r; r = r->next) {
405
		ALLOC_GROW(bb->commits, bb->commits_nr + 1, bb->commits_alloc);
406
		bb->commits[bb->commits_nr++] = r->item;
407
	}
408

409
	trace2_data_intmax("pack-bitmap-write", the_repository,
410
			   "num_selected_commits", writer->selected_nr);
411
	trace2_data_intmax("pack-bitmap-write", the_repository,
412
			   "num_maximal_commits", num_maximal);
413

414
	release_revisions(&revs);
415
	free_commit_list(reusable);
416
}
417

418
static void bitmap_builder_clear(struct bitmap_builder *bb)
419
{
420
	deep_clear_bb_data(&bb->data, clear_bb_commit);
421
	free(bb->commits);
422
	bb->commits_nr = bb->commits_alloc = 0;
423
}
424

425
static int fill_bitmap_tree(struct bitmap_writer *writer,
426
			    struct bitmap *bitmap,
427
			    struct tree *tree)
428
{
429
	int found;
430
	uint32_t pos;
431
	struct tree_desc desc;
432
	struct name_entry entry;
433

434
	/*
435
	 * If our bit is already set, then there is nothing to do. Both this
436
	 * tree and all of its children will be set.
437
	 */
438
	pos = find_object_pos(writer, &tree->object.oid, &found);
439
	if (!found)
440
		return -1;
441
	if (bitmap_get(bitmap, pos))
442
		return 0;
443
	bitmap_set(bitmap, pos);
444

445
	if (parse_tree(tree) < 0)
446
		die("unable to load tree object %s",
447
		    oid_to_hex(&tree->object.oid));
448
	init_tree_desc(&desc, &tree->object.oid, tree->buffer, tree->size);
449

450
	while (tree_entry(&desc, &entry)) {
451
		switch (object_type(entry.mode)) {
452
		case OBJ_TREE:
453
			if (fill_bitmap_tree(writer, bitmap,
454
					     lookup_tree(the_repository, &entry.oid)) < 0)
455
				return -1;
456
			break;
457
		case OBJ_BLOB:
458
			pos = find_object_pos(writer, &entry.oid, &found);
459
			if (!found)
460
				return -1;
461
			bitmap_set(bitmap, pos);
462
			break;
463
		default:
464
			/* Gitlink, etc; not reachable */
465
			break;
466
		}
467
	}
468

469
	free_tree_buffer(tree);
470
	return 0;
471
}
472

473
static int reused_bitmaps_nr;
474
static int reused_pseudo_merge_bitmaps_nr;
475

476
static int fill_bitmap_commit(struct bitmap_writer *writer,
477
			      struct bb_commit *ent,
478
			      struct commit *commit,
479
			      struct prio_queue *queue,
480
			      struct prio_queue *tree_queue,
481
			      struct bitmap_index *old_bitmap,
482
			      const uint32_t *mapping)
483
{
484
	int found;
485
	uint32_t pos;
486
	if (!ent->bitmap)
487
		ent->bitmap = bitmap_new();
488

489
	prio_queue_put(queue, commit);
490

491
	while (queue->nr) {
492
		struct commit_list *p;
493
		struct commit *c = prio_queue_get(queue);
494

495
		if (old_bitmap && mapping) {
496
			struct ewah_bitmap *old;
497
			struct bitmap *remapped = bitmap_new();
498

499
			if (commit->object.flags & BITMAP_PSEUDO_MERGE)
500
				old = pseudo_merge_bitmap_for_commit(old_bitmap, c);
501
			else
502
				old = bitmap_for_commit(old_bitmap, c);
503
			/*
504
			 * If this commit has an old bitmap, then translate that
505
			 * bitmap and add its bits to this one. No need to walk
506
			 * parents or the tree for this commit.
507
			 */
508
			if (old && !rebuild_bitmap(mapping, old, remapped)) {
509
				bitmap_or(ent->bitmap, remapped);
510
				bitmap_free(remapped);
511
				if (commit->object.flags & BITMAP_PSEUDO_MERGE)
512
					reused_pseudo_merge_bitmaps_nr++;
513
				else
514
					reused_bitmaps_nr++;
515
				continue;
516
			}
517
			bitmap_free(remapped);
518
		}
519

520
		/*
521
		 * Mark ourselves and queue our tree. The commit
522
		 * walk ensures we cover all parents.
523
		 */
524
		if (!(c->object.flags & BITMAP_PSEUDO_MERGE)) {
525
			pos = find_object_pos(writer, &c->object.oid, &found);
526
			if (!found)
527
				return -1;
528
			bitmap_set(ent->bitmap, pos);
529
			prio_queue_put(tree_queue,
530
				       repo_get_commit_tree(the_repository, c));
531
		}
532

533
		for (p = c->parents; p; p = p->next) {
534
			pos = find_object_pos(writer, &p->item->object.oid,
535
					      &found);
536
			if (!found)
537
				return -1;
538
			if (!bitmap_get(ent->bitmap, pos)) {
539
				bitmap_set(ent->bitmap, pos);
540
				prio_queue_put(queue, p->item);
541
			}
542
		}
543
	}
544

545
	while (tree_queue->nr) {
546
		if (fill_bitmap_tree(writer, ent->bitmap,
547
				     prio_queue_get(tree_queue)) < 0)
548
			return -1;
549
	}
550
	return 0;
551
}
552

553
static void store_selected(struct bitmap_writer *writer,
554
			   struct bb_commit *ent, struct commit *commit)
555
{
556
	struct bitmapped_commit *stored = &writer->selected[ent->idx];
557
	khiter_t hash_pos;
558

559
	stored->bitmap = bitmap_to_ewah(ent->bitmap);
560

561
	if (ent->pseudo_merge)
562
		return;
563

564
	hash_pos = kh_get_oid_map(writer->bitmaps, commit->object.oid);
565
	if (hash_pos == kh_end(writer->bitmaps))
566
		die(_("attempted to store non-selected commit: '%s'"),
567
		    oid_to_hex(&commit->object.oid));
568

569
	kh_value(writer->bitmaps, hash_pos) = stored;
570
}
571

572
int bitmap_writer_build(struct bitmap_writer *writer)
573
{
574
	struct bitmap_builder bb;
575
	size_t i;
576
	int nr_stored = 0; /* for progress */
577
	struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
578
	struct prio_queue tree_queue = { NULL };
579
	struct bitmap_index *old_bitmap;
580
	uint32_t *mapping;
581
	int closed = 1; /* until proven otherwise */
582

583
	if (writer->show_progress)
584
		writer->progress = start_progress("Building bitmaps",
585
						  writer->selected_nr);
586
	trace2_region_enter("pack-bitmap-write", "building_bitmaps_total",
587
			    the_repository);
588

589
	old_bitmap = prepare_bitmap_git(writer->to_pack->repo);
590
	if (old_bitmap)
591
		mapping = create_bitmap_mapping(old_bitmap, writer->to_pack);
592
	else
593
		mapping = NULL;
594

595
	bitmap_builder_init(&bb, writer, old_bitmap);
596
	for (i = bb.commits_nr; i > 0; i--) {
597
		struct commit *commit = bb.commits[i-1];
598
		struct bb_commit *ent = bb_data_at(&bb.data, commit);
599
		struct commit *child;
600
		int reused = 0;
601

602
		if (fill_bitmap_commit(writer, ent, commit, &queue, &tree_queue,
603
				       old_bitmap, mapping) < 0) {
604
			closed = 0;
605
			break;
606
		}
607

608
		if (ent->selected) {
609
			store_selected(writer, ent, commit);
610
			nr_stored++;
611
			display_progress(writer->progress, nr_stored);
612
		}
613

614
		while ((child = pop_commit(&ent->reverse_edges))) {
615
			struct bb_commit *child_ent =
616
				bb_data_at(&bb.data, child);
617

618
			if (child_ent->bitmap)
619
				bitmap_or(child_ent->bitmap, ent->bitmap);
620
			else if (reused)
621
				child_ent->bitmap = bitmap_dup(ent->bitmap);
622
			else {
623
				child_ent->bitmap = ent->bitmap;
624
				reused = 1;
625
			}
626
		}
627
		if (!reused)
628
			bitmap_free(ent->bitmap);
629
		ent->bitmap = NULL;
630
	}
631
	clear_prio_queue(&queue);
632
	clear_prio_queue(&tree_queue);
633
	bitmap_builder_clear(&bb);
634
	free_bitmap_index(old_bitmap);
635
	free(mapping);
636

637
	trace2_region_leave("pack-bitmap-write", "building_bitmaps_total",
638
			    the_repository);
639
	trace2_data_intmax("pack-bitmap-write", the_repository,
640
			   "building_bitmaps_reused", reused_bitmaps_nr);
641
	trace2_data_intmax("pack-bitmap-write", the_repository,
642
			   "building_bitmaps_pseudo_merge_reused",
643
			   reused_pseudo_merge_bitmaps_nr);
644

645
	stop_progress(&writer->progress);
646

647
	if (closed)
648
		compute_xor_offsets(writer);
649
	return closed ? 0 : -1;
650
}
651

652
/**
653
 * Select the commits that will be bitmapped
654
 */
655
static inline unsigned int next_commit_index(unsigned int idx)
656
{
657
	static const unsigned int MIN_COMMITS = 100;
658
	static const unsigned int MAX_COMMITS = 5000;
659

660
	static const unsigned int MUST_REGION = 100;
661
	static const unsigned int MIN_REGION = 20000;
662

663
	unsigned int offset, next;
664

665
	if (idx <= MUST_REGION)
666
		return 0;
667

668
	if (idx <= MIN_REGION) {
669
		offset = idx - MUST_REGION;
670
		return (offset < MIN_COMMITS) ? offset : MIN_COMMITS;
671
	}
672

673
	offset = idx - MIN_REGION;
674
	next = (offset < MAX_COMMITS) ? offset : MAX_COMMITS;
675

676
	return (next > MIN_COMMITS) ? next : MIN_COMMITS;
677
}
678

679
static int date_compare(const void *_a, const void *_b)
680
{
681
	struct commit *a = *(struct commit **)_a;
682
	struct commit *b = *(struct commit **)_b;
683
	return (long)b->date - (long)a->date;
684
}
685

686
void bitmap_writer_select_commits(struct bitmap_writer *writer,
687
				  struct commit **indexed_commits,
688
				  unsigned int indexed_commits_nr)
689
{
690
	unsigned int i = 0, j, next;
691

692
	QSORT(indexed_commits, indexed_commits_nr, date_compare);
693

694
	if (indexed_commits_nr < 100) {
695
		for (i = 0; i < indexed_commits_nr; ++i)
696
			bitmap_writer_push_commit(writer, indexed_commits[i], 0);
697

698
		select_pseudo_merges(writer);
699

700
		return;
701
	}
702

703
	if (writer->show_progress)
704
		writer->progress = start_progress("Selecting bitmap commits", 0);
705

706
	for (;;) {
707
		struct commit *chosen = NULL;
708

709
		next = next_commit_index(i);
710

711
		if (i + next >= indexed_commits_nr)
712
			break;
713

714
		if (next == 0) {
715
			chosen = indexed_commits[i];
716
		} else {
717
			chosen = indexed_commits[i + next];
718

719
			for (j = 0; j <= next; ++j) {
720
				struct commit *cm = indexed_commits[i + j];
721

722
				if ((cm->object.flags & NEEDS_BITMAP) != 0) {
723
					chosen = cm;
724
					break;
725
				}
726

727
				if (cm->parents && cm->parents->next)
728
					chosen = cm;
729
			}
730
		}
731

732
		bitmap_writer_push_commit(writer, chosen, 0);
733

734
		i += next + 1;
735
		display_progress(writer->progress, i);
736
	}
737

738
	stop_progress(&writer->progress);
739

740
	select_pseudo_merges(writer);
741
}
742

743

744
static int hashwrite_ewah_helper(void *f, const void *buf, size_t len)
745
{
746
	/* hashwrite will die on error */
747
	hashwrite(f, buf, len);
748
	return len;
749
}
750

751
/**
752
 * Write the bitmap index to disk
753
 */
754
static inline void dump_bitmap(struct hashfile *f, struct ewah_bitmap *bitmap)
755
{
756
	if (ewah_serialize_to(bitmap, hashwrite_ewah_helper, f) < 0)
757
		die("Failed to write bitmap index");
758
}
759

760
static const struct object_id *oid_access(size_t pos, const void *table)
761
{
762
	const struct pack_idx_entry * const *index = table;
763
	return &index[pos]->oid;
764
}
765

766
static void write_selected_commits_v1(struct bitmap_writer *writer,
767
				      struct hashfile *f, off_t *offsets)
768
{
769
	int i;
770

771
	for (i = 0; i < bitmap_writer_nr_selected_commits(writer); ++i) {
772
		struct bitmapped_commit *stored = &writer->selected[i];
773
		if (stored->pseudo_merge)
774
			BUG("unexpected pseudo-merge among selected: %s",
775
			    oid_to_hex(&stored->commit->object.oid));
776

777
		if (offsets)
778
			offsets[i] = hashfile_total(f);
779

780
		hashwrite_be32(f, stored->commit_pos);
781
		hashwrite_u8(f, stored->xor_offset);
782
		hashwrite_u8(f, stored->flags);
783

784
		dump_bitmap(f, stored->write_as);
785
	}
786
}
787

788
static void write_pseudo_merges(struct bitmap_writer *writer,
789
				struct hashfile *f)
790
{
791
	struct oid_array commits = OID_ARRAY_INIT;
792
	struct bitmap **commits_bitmap = NULL;
793
	off_t *pseudo_merge_ofs = NULL;
794
	off_t start, table_start, next_ext;
795

796
	uint32_t base = bitmap_writer_nr_selected_commits(writer);
797
	size_t i, j = 0;
798

799
	CALLOC_ARRAY(commits_bitmap, writer->pseudo_merges_nr);
800
	CALLOC_ARRAY(pseudo_merge_ofs, writer->pseudo_merges_nr);
801

802
	for (i = 0; i < writer->pseudo_merges_nr; i++) {
803
		struct bitmapped_commit *merge = &writer->selected[base + i];
804
		struct commit_list *p;
805

806
		if (!merge->pseudo_merge)
807
			BUG("found non-pseudo merge commit at %"PRIuMAX, (uintmax_t)i);
808

809
		commits_bitmap[i] = bitmap_new();
810

811
		for (p = merge->commit->parents; p; p = p->next)
812
			bitmap_set(commits_bitmap[i],
813
				   find_object_pos(writer, &p->item->object.oid,
814
						   NULL));
815
	}
816

817
	start = hashfile_total(f);
818

819
	for (i = 0; i < writer->pseudo_merges_nr; i++) {
820
		struct ewah_bitmap *commits_ewah = bitmap_to_ewah(commits_bitmap[i]);
821

822
		pseudo_merge_ofs[i] = hashfile_total(f);
823

824
		dump_bitmap(f, commits_ewah);
825
		dump_bitmap(f, writer->selected[base+i].write_as);
826

827
		ewah_free(commits_ewah);
828
	}
829

830
	next_ext = st_add(hashfile_total(f),
831
			  st_mult(kh_size(writer->pseudo_merge_commits),
832
				  sizeof(uint64_t)));
833

834
	table_start = hashfile_total(f);
835

836
	commits.alloc = kh_size(writer->pseudo_merge_commits);
837
	CALLOC_ARRAY(commits.oid, commits.alloc);
838

839
	for (i = kh_begin(writer->pseudo_merge_commits); i != kh_end(writer->pseudo_merge_commits); i++) {
840
		if (!kh_exist(writer->pseudo_merge_commits, i))
841
			continue;
842
		oid_array_append(&commits, &kh_key(writer->pseudo_merge_commits, i));
843
	}
844

845
	oid_array_sort(&commits);
846

847
	/* write lookup table (non-extended) */
848
	for (i = 0; i < commits.nr; i++) {
849
		int hash_pos;
850
		struct pseudo_merge_commit_idx *c;
851

852
		hash_pos = kh_get_oid_map(writer->pseudo_merge_commits,
853
					  commits.oid[i]);
854
		if (hash_pos == kh_end(writer->pseudo_merge_commits))
855
			BUG("could not find pseudo-merge commit %s",
856
			    oid_to_hex(&commits.oid[i]));
857

858
		c = kh_value(writer->pseudo_merge_commits, hash_pos);
859

860
		hashwrite_be32(f, find_object_pos(writer, &commits.oid[i],
861
						  NULL));
862
		if (c->nr == 1)
863
			hashwrite_be64(f, pseudo_merge_ofs[c->pseudo_merge[0]]);
864
		else if (c->nr > 1) {
865
			if (next_ext & ((uint64_t)1<<63))
866
				die(_("too many pseudo-merges"));
867
			hashwrite_be64(f, next_ext | ((uint64_t)1<<63));
868
			next_ext = st_add3(next_ext,
869
					   sizeof(uint32_t),
870
					   st_mult(c->nr, sizeof(uint64_t)));
871
		} else
872
			BUG("expected commit '%s' to have at least one "
873
			    "pseudo-merge", oid_to_hex(&commits.oid[i]));
874
	}
875

876
	/* write lookup table (extended) */
877
	for (i = 0; i < commits.nr; i++) {
878
		int hash_pos;
879
		struct pseudo_merge_commit_idx *c;
880

881
		hash_pos = kh_get_oid_map(writer->pseudo_merge_commits,
882
					  commits.oid[i]);
883
		if (hash_pos == kh_end(writer->pseudo_merge_commits))
884
			BUG("could not find pseudo-merge commit %s",
885
			    oid_to_hex(&commits.oid[i]));
886

887
		c = kh_value(writer->pseudo_merge_commits, hash_pos);
888
		if (c->nr == 1)
889
			continue;
890

891
		hashwrite_be32(f, c->nr);
892
		for (j = 0; j < c->nr; j++)
893
			hashwrite_be64(f, pseudo_merge_ofs[c->pseudo_merge[j]]);
894
	}
895

896
	/* write positions for all pseudo merges */
897
	for (i = 0; i < writer->pseudo_merges_nr; i++)
898
		hashwrite_be64(f, pseudo_merge_ofs[i]);
899

900
	hashwrite_be32(f, writer->pseudo_merges_nr);
901
	hashwrite_be32(f, kh_size(writer->pseudo_merge_commits));
902
	hashwrite_be64(f, table_start - start);
903
	hashwrite_be64(f, hashfile_total(f) - start + sizeof(uint64_t));
904

905
	for (i = 0; i < writer->pseudo_merges_nr; i++)
906
		bitmap_free(commits_bitmap[i]);
907

908
	free(pseudo_merge_ofs);
909
	free(commits_bitmap);
910
}
911

912
static int table_cmp(const void *_va, const void *_vb, void *_data)
913
{
914
	struct bitmap_writer *writer = _data;
915
	struct bitmapped_commit *a = &writer->selected[*(uint32_t *)_va];
916
	struct bitmapped_commit *b = &writer->selected[*(uint32_t *)_vb];
917

918
	if (a->commit_pos < b->commit_pos)
919
		return -1;
920
	else if (a->commit_pos > b->commit_pos)
921
		return 1;
922

923
	return 0;
924
}
925

926
static void write_lookup_table(struct bitmap_writer *writer, struct hashfile *f,
927
			       off_t *offsets)
928
{
929
	uint32_t i;
930
	uint32_t *table, *table_inv;
931

932
	ALLOC_ARRAY(table, bitmap_writer_nr_selected_commits(writer));
933
	ALLOC_ARRAY(table_inv, bitmap_writer_nr_selected_commits(writer));
934

935
	for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++)
936
		table[i] = i;
937

938
	/*
939
	 * At the end of this sort table[j] = i means that the i'th
940
	 * bitmap corresponds to j'th bitmapped commit (among the selected
941
	 * commits) in lex order of OIDs.
942
	 */
943
	QSORT_S(table, bitmap_writer_nr_selected_commits(writer), table_cmp, writer);
944

945
	/* table_inv helps us discover that relationship (i'th bitmap
946
	 * to j'th commit by j = table_inv[i])
947
	 */
948
	for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++)
949
		table_inv[table[i]] = i;
950

951
	trace2_region_enter("pack-bitmap-write", "writing_lookup_table", the_repository);
952
	for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++) {
953
		struct bitmapped_commit *selected = &writer->selected[table[i]];
954
		uint32_t xor_offset = selected->xor_offset;
955
		uint32_t xor_row;
956

957
		if (xor_offset) {
958
			/*
959
			 * xor_index stores the index (in the bitmap entries)
960
			 * of the corresponding xor bitmap. But we need to convert
961
			 * this index into lookup table's index. So, table_inv[xor_index]
962
			 * gives us the index position w.r.t. the lookup table.
963
			 *
964
			 * If "k = table[i] - xor_offset" then the xor base is the k'th
965
			 * bitmap. `table_inv[k]` gives us the position of that bitmap
966
			 * in the lookup table.
967
			 */
968
			uint32_t xor_index = table[i] - xor_offset;
969
			xor_row = table_inv[xor_index];
970
		} else {
971
			xor_row = 0xffffffff;
972
		}
973

974
		hashwrite_be32(f, writer->selected[table[i]].commit_pos);
975
		hashwrite_be64(f, (uint64_t)offsets[table[i]]);
976
		hashwrite_be32(f, xor_row);
977
	}
978
	trace2_region_leave("pack-bitmap-write", "writing_lookup_table", the_repository);
979

980
	free(table);
981
	free(table_inv);
982
}
983

984
static void write_hash_cache(struct hashfile *f,
985
			     struct pack_idx_entry **index,
986
			     uint32_t index_nr)
987
{
988
	uint32_t i;
989

990
	for (i = 0; i < index_nr; ++i) {
991
		struct object_entry *entry = (struct object_entry *)index[i];
992
		hashwrite_be32(f, entry->hash);
993
	}
994
}
995

996
void bitmap_writer_set_checksum(struct bitmap_writer *writer,
997
				const unsigned char *sha1)
998
{
999
	hashcpy(writer->pack_checksum, sha1, the_repository->hash_algo);
1000
}
1001

1002
void bitmap_writer_finish(struct bitmap_writer *writer,
1003
			  struct pack_idx_entry **index,
1004
			  const char *filename,
1005
			  uint16_t options)
1006
{
1007
	static uint16_t default_version = 1;
1008
	static uint16_t flags = BITMAP_OPT_FULL_DAG;
1009
	struct strbuf tmp_file = STRBUF_INIT;
1010
	struct hashfile *f;
1011
	off_t *offsets = NULL;
1012
	uint32_t i;
1013

1014
	struct bitmap_disk_header header;
1015

1016
	int fd = odb_mkstemp(&tmp_file, "pack/tmp_bitmap_XXXXXX");
1017

1018
	if (writer->pseudo_merges_nr)
1019
		options |= BITMAP_OPT_PSEUDO_MERGES;
1020

1021
	f = hashfd(fd, tmp_file.buf);
1022

1023
	memcpy(header.magic, BITMAP_IDX_SIGNATURE, sizeof(BITMAP_IDX_SIGNATURE));
1024
	header.version = htons(default_version);
1025
	header.options = htons(flags | options);
1026
	header.entry_count = htonl(bitmap_writer_nr_selected_commits(writer));
1027
	hashcpy(header.checksum, writer->pack_checksum, the_repository->hash_algo);
1028

1029
	hashwrite(f, &header, sizeof(header) - GIT_MAX_RAWSZ + the_hash_algo->rawsz);
1030
	dump_bitmap(f, writer->commits);
1031
	dump_bitmap(f, writer->trees);
1032
	dump_bitmap(f, writer->blobs);
1033
	dump_bitmap(f, writer->tags);
1034

1035
	if (options & BITMAP_OPT_LOOKUP_TABLE)
1036
		CALLOC_ARRAY(offsets, writer->to_pack->nr_objects);
1037

1038
	for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++) {
1039
		struct bitmapped_commit *stored = &writer->selected[i];
1040
		int commit_pos = oid_pos(&stored->commit->object.oid, index,
1041
					 writer->to_pack->nr_objects,
1042
					 oid_access);
1043

1044
		if (commit_pos < 0)
1045
			BUG(_("trying to write commit not in index"));
1046
		stored->commit_pos = commit_pos;
1047
	}
1048

1049
	write_selected_commits_v1(writer, f, offsets);
1050

1051
	if (options & BITMAP_OPT_PSEUDO_MERGES)
1052
		write_pseudo_merges(writer, f);
1053

1054
	if (options & BITMAP_OPT_LOOKUP_TABLE)
1055
		write_lookup_table(writer, f, offsets);
1056

1057
	if (options & BITMAP_OPT_HASH_CACHE)
1058
		write_hash_cache(f, index, writer->to_pack->nr_objects);
1059

1060
	finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
1061
			  CSUM_HASH_IN_STREAM | CSUM_FSYNC | CSUM_CLOSE);
1062

1063
	if (adjust_shared_perm(tmp_file.buf))
1064
		die_errno("unable to make temporary bitmap file readable");
1065

1066
	if (rename(tmp_file.buf, filename))
1067
		die_errno("unable to rename temporary bitmap file to '%s'", filename);
1068

1069
	strbuf_release(&tmp_file);
1070
	free(offsets);
1071
}
1072

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.