1
+#include "cache.h"
2
+#include "commit.h"
3
+#include "tag.h"
4
+#include "diff.h"
5
+#include "revision.h"
6
+#include "progress.h"
7
+#include "list-objects.h"
8
+#include "pack.h"
9
+#include "pack-bitmap.h"
10
+#include "pack-revindex.h"
11
+#include "pack-objects.h"
12
+
13
+/*
14
+ * An entry on the bitmap index, representing the bitmap for a given
15
+ * commit.
16
+ */
17
+struct stored_bitmap {
18
+ unsigned char sha1[20];
19
+ struct ewah_bitmap *root;
20
+ struct stored_bitmap *xor;
21
+ int flags;
22
+};
23
+
24
+/*
25
+ * The currently active bitmap index. By design, repositories only have
26
+ * a single bitmap index available (the index for the biggest packfile in
27
+ * the repository), since bitmap indexes need full closure.
28
+ *
29
+ * If there is more than one bitmap index available (e.g. because of alternates),
30
+ * the active bitmap index is the largest one.
31
+ */
32
+static struct bitmap_index {
33
+ /* Packfile to which this bitmap index belongs to */
34
+ struct packed_git *pack;
35
+
36
+ /* reverse index for the packfile */
37
+ struct pack_revindex *reverse_index;
38
+
39
+ /*
40
+ * Mark the first `reuse_objects` in the packfile as reused:
41
+ * they will be sent as-is without using them for repacking
42
+ * calculations
43
+ */
44
+ uint32_t reuse_objects;
45
+
46
+ /* mmapped buffer of the whole bitmap index */
47
+ unsigned char *map;
48
+ size_t map_size; /* size of the mmaped buffer */
49
+ size_t map_pos; /* current position when loading the index */
50
+
51
+ /*
52
+ * Type indexes.
53
+ *
54
+ * Each bitmap marks which objects in the packfile are of the given
55
+ * type. This provides type information when yielding the objects from
56
+ * the packfile during a walk, which allows for better delta bases.
57
+ */
58
+ struct ewah_bitmap *commits;
59
+ struct ewah_bitmap *trees;
60
+ struct ewah_bitmap *blobs;
61
+ struct ewah_bitmap *tags;
62
+
63
+ /* Map from SHA1 -> `stored_bitmap` for all the bitmapped comits */
64
+ khash_sha1 *bitmaps;
65
+
66
+ /* Number of bitmapped commits */
67
+ uint32_t entry_count;
68
+
69
+ /*
70
+ * Extended index.
71
+ *
72
+ * When trying to perform bitmap operations with objects that are not
73
+ * packed in `pack`, these objects are added to this "fake index" and
74
+ * are assumed to appear at the end of the packfile for all operations
75
+ */
76
+ struct eindex {
77
+ struct object **objects;
78
+ uint32_t *hashes;
79
+ uint32_t count, alloc;
80
+ khash_sha1_pos *positions;
81
+ } ext_index;
82
+
83
+ /* Bitmap result of the last performed walk */
84
+ struct bitmap *result;
85
+
86
+ /* Version of the bitmap index */
87
+ unsigned int version;
88
+
89
+ unsigned loaded : 1;
90
+
91
+} bitmap_git;
92
+
93
+static struct ewah_bitmap *lookup_stored_bitmap(struct stored_bitmap *st)
94
+{
95
+ struct ewah_bitmap *parent;
96
+ struct ewah_bitmap *composed;
97
+
98
+ if (st->xor == NULL)
99
+ return st->root;
100
+
101
+ composed = ewah_pool_new();
102
+ parent = lookup_stored_bitmap(st->xor);
103
+ ewah_xor(st->root, parent, composed);
104
+
105
+ ewah_pool_free(st->root);
106
+ st->root = composed;
107
+ st->xor = NULL;
108
+
109
+ return composed;
110
+}
111
+
112
+/*
113
+ * Read a bitmap from the current read position on the mmaped
114
+ * index, and increase the read position accordingly
115
+ */
116
+static struct ewah_bitmap *read_bitmap_1(struct bitmap_index *index)
117
+{
118
+ struct ewah_bitmap *b = ewah_pool_new();
119
+
120
+ int bitmap_size = ewah_read_mmap(b,
121
+ index->map + index->map_pos,
122
+ index->map_size - index->map_pos);
123
+
124
+ if (bitmap_size < 0) {
125
+ error("Failed to load bitmap index (corrupted?)");
126
+ ewah_pool_free(b);
127
+ return NULL;
128
+ }
129
+
130
+ index->map_pos += bitmap_size;
131
+ return b;
132
+}
133
+
134
+static int load_bitmap_header(struct bitmap_index *index)
135
+{
136
+ struct bitmap_disk_header *header = (void *)index->map;
137
+
138
+ if (index->map_size < sizeof(*header) + 20)
139
+ return error("Corrupted bitmap index (missing header data)");
140
+
141
+ if (memcmp(header->magic, BITMAP_IDX_SIGNATURE, sizeof(BITMAP_IDX_SIGNATURE)) != 0)
142
+ return error("Corrupted bitmap index file (wrong header)");
143
+
144
+ index->version = ntohs(header->version);
145
+ if (index->version != 1)
146
+ return error("Unsupported version for bitmap index file (%d)", index->version);
147
+
148
+ /* Parse known bitmap format options */
149
+ {
150
+ uint32_t flags = ntohs(header->options);
151
+
152
+ if ((flags & BITMAP_OPT_FULL_DAG) == 0)
153
+ return error("Unsupported options for bitmap index file "
154
+ "(Git requires BITMAP_OPT_FULL_DAG)");
155
+ }
156
+
157
+ index->entry_count = ntohl(header->entry_count);
158
+ index->map_pos += sizeof(*header);
159
+ return 0;
160
+}
161
+
162
+static struct stored_bitmap *store_bitmap(struct bitmap_index *index,
163
+ struct ewah_bitmap *root,
164
+ const unsigned char *sha1,
165
+ struct stored_bitmap *xor_with,
166
+ int flags)
167
+{
168
+ struct stored_bitmap *stored;
169
+ khiter_t hash_pos;
170
+ int ret;
171
+
172
+ stored = xmalloc(sizeof(struct stored_bitmap));
173
+ stored->root = root;
174
+ stored->xor = xor_with;
175
+ stored->flags = flags;
176
+ hashcpy(stored->sha1, sha1);
177
+
178
+ hash_pos = kh_put_sha1(index->bitmaps, stored->sha1, &ret);
179
+
180
+ /* a 0 return code means the insertion succeeded with no changes,
181
+ * because the SHA1 already existed on the map. this is bad, there
182
+ * shouldn't be duplicated commits in the index */
183
+ if (ret == 0) {
184
+ error("Duplicate entry in bitmap index: %s", sha1_to_hex(sha1));
185
+ return NULL;
186
+ }
187
+
188
+ kh_value(index->bitmaps, hash_pos) = stored;
189
+ return stored;
190
+}
191
+
192
+static int load_bitmap_entries_v1(struct bitmap_index *index)
193
+{
194
+ static const size_t MAX_XOR_OFFSET = 160;
195
+
196
+ uint32_t i;
197
+ struct stored_bitmap **recent_bitmaps;
198
+ struct bitmap_disk_entry *entry;
199
+
200
+ recent_bitmaps = xcalloc(MAX_XOR_OFFSET, sizeof(struct stored_bitmap));
201
+
202
+ for (i = 0; i < index->entry_count; ++i) {
203
+ int xor_offset, flags;
204
+ struct ewah_bitmap *bitmap = NULL;
205
+ struct stored_bitmap *xor_bitmap = NULL;
206
+ uint32_t commit_idx_pos;
207
+ const unsigned char *sha1;
208
+
209
+ entry = (struct bitmap_disk_entry *)(index->map + index->map_pos);
210
+ index->map_pos += sizeof(struct bitmap_disk_entry);
211
+
212
+ commit_idx_pos = ntohl(entry->object_pos);
213
+ sha1 = nth_packed_object_sha1(index->pack, commit_idx_pos);
214
+
215
+ xor_offset = (int)entry->xor_offset;
216
+ flags = (int)entry->flags;
217
+
218
+ bitmap = read_bitmap_1(index);
219
+ if (!bitmap)
220
+ return -1;
221
+
222
+ if (xor_offset > MAX_XOR_OFFSET || xor_offset > i)
223
+ return error("Corrupted bitmap pack index");
224
+
225
+ if (xor_offset > 0) {
226
+ xor_bitmap = recent_bitmaps[(i - xor_offset) % MAX_XOR_OFFSET];
227
+
228
+ if (xor_bitmap == NULL)
229
+ return error("Invalid XOR offset in bitmap pack index");
230
+ }
231
+
232
+ recent_bitmaps[i % MAX_XOR_OFFSET] = store_bitmap(
233
+ index, bitmap, sha1, xor_bitmap, flags);
234
+ }
235
+
236
+ return 0;
237
+}
238
+
239
+static int open_pack_bitmap_1(struct packed_git *packfile)
240
+{
241
+ int fd;
242
+ struct stat st;
243
+ char *idx_name;
244
+
245
+ if (open_pack_index(packfile))
246
+ return -1;
247
+
248
+ idx_name = pack_bitmap_filename(packfile);
249
+ fd = git_open_noatime(idx_name);
250
+ free(idx_name);
251
+
252
+ if (fd < 0)
253
+ return -1;
254
+
255
+ if (fstat(fd, &st)) {
256
+ close(fd);
257
+ return -1;
258
+ }
259
+
260
+ if (bitmap_git.pack) {
261
+ warning("ignoring extra bitmap file: %s", packfile->pack_name);
262
+ close(fd);
263
+ return -1;
264
+ }
265
+
266
+ bitmap_git.pack = packfile;
267
+ bitmap_git.map_size = xsize_t(st.st_size);
268
+ bitmap_git.map = xmmap(NULL, bitmap_git.map_size, PROT_READ, MAP_PRIVATE, fd, 0);
269
+ bitmap_git.map_pos = 0;
270
+ close(fd);
271
+
272
+ if (load_bitmap_header(&bitmap_git) < 0) {
273
+ munmap(bitmap_git.map, bitmap_git.map_size);
274
+ bitmap_git.map = NULL;
275
+ bitmap_git.map_size = 0;
276
+ return -1;
277
+ }
278
+
279
+ return 0;
280
+}
281
+
282
+static int load_pack_bitmap(void)
283
+{
284
+ assert(bitmap_git.map && !bitmap_git.loaded);
285
+
286
+ bitmap_git.bitmaps = kh_init_sha1();
287
+ bitmap_git.ext_index.positions = kh_init_sha1_pos();
288
+ bitmap_git.reverse_index = revindex_for_pack(bitmap_git.pack);
289
+
290
+ if (!(bitmap_git.commits = read_bitmap_1(&bitmap_git)) ||
291
+ !(bitmap_git.trees = read_bitmap_1(&bitmap_git)) ||
292
+ !(bitmap_git.blobs = read_bitmap_1(&bitmap_git)) ||
293
+ !(bitmap_git.tags = read_bitmap_1(&bitmap_git)))
294
+ goto failed;
295
+
296
+ if (load_bitmap_entries_v1(&bitmap_git) < 0)
297
+ goto failed;
298
+
299
+ bitmap_git.loaded = 1;
300
+ return 0;
301
+
302
+failed:
303
+ munmap(bitmap_git.map, bitmap_git.map_size);
304
+ bitmap_git.map = NULL;
305
+ bitmap_git.map_size = 0;
306
+ return -1;
307
+}
308
+
309
+char *pack_bitmap_filename(struct packed_git *p)
310
+{
311
+ char *idx_name;
312
+ int len;
313
+
314
+ len = strlen(p->pack_name) - strlen(".pack");
315
+ idx_name = xmalloc(len + strlen(".bitmap") + 1);
316
+
317
+ memcpy(idx_name, p->pack_name, len);
318
+ memcpy(idx_name + len, ".bitmap", strlen(".bitmap") + 1);
319
+
320
+ return idx_name;
321
+}
322
+
323
+static int open_pack_bitmap(void)
324
+{
325
+ struct packed_git *p;
326
+ int ret = -1;
327
+
328
+ assert(!bitmap_git.map && !bitmap_git.loaded);
329
+
330
+ prepare_packed_git();
331
+ for (p = packed_git; p; p = p->next) {
332
+ if (open_pack_bitmap_1(p) == 0)
333
+ ret = 0;
334
+ }
335
+
336
+ return ret;
337
+}
338
+
339
+int prepare_bitmap_git(void)
340
+{
341
+ if (bitmap_git.loaded)
342
+ return 0;
343
+
344
+ if (!open_pack_bitmap())
345
+ return load_pack_bitmap();
346
+
347
+ return -1;
348
+}
349
+
350
+struct include_data {
351
+ struct bitmap *base;
352
+ struct bitmap *seen;
353
+};
354
+
355
+static inline int bitmap_position_extended(const unsigned char *sha1)
356
+{
357
+ khash_sha1_pos *positions = bitmap_git.ext_index.positions;
358
+ khiter_t pos = kh_get_sha1_pos(positions, sha1);
359
+
360
+ if (pos < kh_end(positions)) {
361
+ int bitmap_pos = kh_value(positions, pos);
362
+ return bitmap_pos + bitmap_git.pack->num_objects;
363
+ }
364
+
365
+ return -1;
366
+}
367
+
368
+static inline int bitmap_position_packfile(const unsigned char *sha1)
369
+{
370
+ off_t offset = find_pack_entry_one(sha1, bitmap_git.pack);
371
+ if (!offset)
372
+ return -1;
373
+
374
+ return find_revindex_position(bitmap_git.reverse_index, offset);
375
+}
376
+
377
+static int bitmap_position(const unsigned char *sha1)
378
+{
379
+ int pos = bitmap_position_packfile(sha1);
380
+ return (pos >= 0) ? pos : bitmap_position_extended(sha1);
381
+}
382
+
383
+static int ext_index_add_object(struct object *object, const char *name)
384
+{
385
+ struct eindex *eindex = &bitmap_git.ext_index;
386
+
387
+ khiter_t hash_pos;
388
+ int hash_ret;
389
+ int bitmap_pos;
390
+
391
+ hash_pos = kh_put_sha1_pos(eindex->positions, object->sha1, &hash_ret);
392
+ if (hash_ret > 0) {
393
+ if (eindex->count >= eindex->alloc) {
394
+ eindex->alloc = (eindex->alloc + 16) * 3 / 2;
395
+ eindex->objects = xrealloc(eindex->objects,
396
+ eindex->alloc * sizeof(struct object *));
397
+ eindex->hashes = xrealloc(eindex->hashes,
398
+ eindex->alloc * sizeof(uint32_t));
399
+ }
400
+
401
+ bitmap_pos = eindex->count;
402
+ eindex->objects[eindex->count] = object;
403
+ eindex->hashes[eindex->count] = pack_name_hash(name);
404
+ kh_value(eindex->positions, hash_pos) = bitmap_pos;
405
+ eindex->count++;
406
+ } else {
407
+ bitmap_pos = kh_value(eindex->positions, hash_pos);
408
+ }
409
+
410
+ return bitmap_pos + bitmap_git.pack->num_objects;
411
+}
412
+
413
+static void show_object(struct object *object, const struct name_path *path,
414
+ const char *last, void *data)
415
+{
416
+ struct bitmap *base = data;
417
+ int bitmap_pos;
418
+
419
+ bitmap_pos = bitmap_position(object->sha1);
420
+
421
+ if (bitmap_pos < 0) {
422
+ char *name = path_name(path, last);
423
+ bitmap_pos = ext_index_add_object(object, name);
424
+ free(name);
425
+ }
426
+
427
+ bitmap_set(base, bitmap_pos);
428
+}
429
+
430
+static void show_commit(struct commit *commit, void *data)
431
+{
432
+}
433
+
434
+static int add_to_include_set(struct include_data *data,
435
+ const unsigned char *sha1,
436
+ int bitmap_pos)
437
+{
438
+ khiter_t hash_pos;
439
+
440
+ if (data->seen && bitmap_get(data->seen, bitmap_pos))
441
+ return 0;
442
+
443
+ if (bitmap_get(data->base, bitmap_pos))
444
+ return 0;
445
+
446
+ hash_pos = kh_get_sha1(bitmap_git.bitmaps, sha1);
447
+ if (hash_pos < kh_end(bitmap_git.bitmaps)) {
448
+ struct stored_bitmap *st = kh_value(bitmap_git.bitmaps, hash_pos);
449
+ bitmap_or_ewah(data->base, lookup_stored_bitmap(st));
450
+ return 0;
451
+ }
452
+
453
+ bitmap_set(data->base, bitmap_pos);
454
+ return 1;
455
+}
456
+
457
+static int should_include(struct commit *commit, void *_data)
458
+{
459
+ struct include_data *data = _data;
460
+ int bitmap_pos;
461
+
462
+ bitmap_pos = bitmap_position(commit->object.sha1);
463
+ if (bitmap_pos < 0)
464
+ bitmap_pos = ext_index_add_object((struct object *)commit, NULL);
465
+
466
+ if (!add_to_include_set(data, commit->object.sha1, bitmap_pos)) {
467
+ struct commit_list *parent = commit->parents;
468
+
469
+ while (parent) {
470
+ parent->item->object.flags |= SEEN;
471
+ parent = parent->next;
472
+ }
473
+
474
+ return 0;
475
+ }
476
+
477
+ return 1;
478
+}
479
+
480
+static struct bitmap *find_objects(struct rev_info *revs,
481
+ struct object_list *roots,
482
+ struct bitmap *seen)
483
+{
484
+ struct bitmap *base = NULL;
485
+ int needs_walk = 0;
486
+
487
+ struct object_list *not_mapped = NULL;
488
+
489
+ /*
490
+ * Go through all the roots for the walk. The ones that have bitmaps
491
+ * on the bitmap index will be `or`ed together to form an initial
492
+ * global reachability analysis.
493
+ *
494
+ * The ones without bitmaps in the index will be stored in the
495
+ * `not_mapped_list` for further processing.
496
+ */
497
+ while (roots) {
498
+ struct object *object = roots->item;
499
+ roots = roots->next;
500
+
501
+ if (object->type == OBJ_COMMIT) {
502
+ khiter_t pos = kh_get_sha1(bitmap_git.bitmaps, object->sha1);
503
+
504
+ if (pos < kh_end(bitmap_git.bitmaps)) {
505
+ struct stored_bitmap *st = kh_value(bitmap_git.bitmaps, pos);
506
+ struct ewah_bitmap *or_with = lookup_stored_bitmap(st);
507
+
508
+ if (base == NULL)
509
+ base = ewah_to_bitmap(or_with);
510
+ else
511
+ bitmap_or_ewah(base, or_with);
512
+
513
+ object->flags |= SEEN;
514
+ continue;
515
+ }
516
+ }
517
+
518
+ object_list_insert(object, ¬_mapped);
519
+ }
520
+
521
+ /*
522
+ * Best case scenario: We found bitmaps for all the roots,
523
+ * so the resulting `or` bitmap has the full reachability analysis
524
+ */
525
+ if (not_mapped == NULL)
526
+ return base;
527
+
528
+ roots = not_mapped;
529
+
530
+ /*
531
+ * Let's iterate through all the roots that don't have bitmaps to
532
+ * check if we can determine them to be reachable from the existing
533
+ * global bitmap.
534
+ *
535
+ * If we cannot find them in the existing global bitmap, we'll need
536
+ * to push them to an actual walk and run it until we can confirm
537
+ * they are reachable
538
+ */
539
+ while (roots) {
540
+ struct object *object = roots->item;
541
+ int pos;
542
+
543
+ roots = roots->next;
544
+ pos = bitmap_position(object->sha1);
545
+
546
+ if (pos < 0 || base == NULL || !bitmap_get(base, pos)) {
547
+ object->flags &= ~UNINTERESTING;
548
+ add_pending_object(revs, object, "");
549
+ needs_walk = 1;
550
+ } else {
551
+ object->flags |= SEEN;
552
+ }
553
+ }
554
+
555
+ if (needs_walk) {
556
+ struct include_data incdata;
557
+
558
+ if (base == NULL)
559
+ base = bitmap_new();
560
+
561
+ incdata.base = base;
562
+ incdata.seen = seen;
563
+
564
+ revs->include_check = should_include;
565
+ revs->include_check_data = &incdata;
566
+
567
+ if (prepare_revision_walk(revs))
568
+ die("revision walk setup failed");
569
+
570
+ traverse_commit_list(revs, show_commit, show_object, base);
571
+ }
572
+
573
+ return base;
574
+}
575
+
576
+static void show_extended_objects(struct bitmap *objects,
577
+ show_reachable_fn show_reach)
578
+{
579
+ struct eindex *eindex = &bitmap_git.ext_index;
580
+ uint32_t i;
581
+
582
+ for (i = 0; i < eindex->count; ++i) {
583
+ struct object *obj;
584
+
585
+ if (!bitmap_get(objects, bitmap_git.pack->num_objects + i))
586
+ continue;
587
+
588
+ obj = eindex->objects[i];
589
+ show_reach(obj->sha1, obj->type, 0, eindex->hashes[i], NULL, 0);
590
+ }
591
+}
592
+
593
+static void show_objects_for_type(
594
+ struct bitmap *objects,
595
+ struct ewah_bitmap *type_filter,
596
+ enum object_type object_type,
597
+ show_reachable_fn show_reach)
598
+{
599
+ size_t pos = 0, i = 0;
600
+ uint32_t offset;
601
+
602
+ struct ewah_iterator it;
603
+ eword_t filter;
604
+
605
+ if (bitmap_git.reuse_objects == bitmap_git.pack->num_objects)
606
+ return;
607
+
608
+ ewah_iterator_init(&it, type_filter);
609
+
610
+ while (i < objects->word_alloc && ewah_iterator_next(&filter, &it)) {
611
+ eword_t word = objects->words[i] & filter;
612
+
613
+ for (offset = 0; offset < BITS_IN_WORD; ++offset) {
614
+ const unsigned char *sha1;
615
+ struct revindex_entry *entry;
616
+ uint32_t hash = 0;
617
+
618
+ if ((word >> offset) == 0)
619
+ break;
620
+
621
+ offset += ewah_bit_ctz64(word >> offset);
622
+
623
+ if (pos + offset < bitmap_git.reuse_objects)
624
+ continue;
625
+
626
+ entry = &bitmap_git.reverse_index->revindex[pos + offset];
627
+ sha1 = nth_packed_object_sha1(bitmap_git.pack, entry->nr);
628
+
629
+ show_reach(sha1, object_type, 0, hash, bitmap_git.pack, entry->offset);
630
+ }
631
+
632
+ pos += BITS_IN_WORD;
633
+ i++;
634
+ }
635
+}
636
+
637
+static int in_bitmapped_pack(struct object_list *roots)
638
+{
639
+ while (roots) {
640
+ struct object *object = roots->item;
641
+ roots = roots->next;
642
+
643
+ if (find_pack_entry_one(object->sha1, bitmap_git.pack) > 0)
644
+ return 1;
645
+ }
646
+
647
+ return 0;
648
+}
649
+
650
+int prepare_bitmap_walk(struct rev_info *revs)
651
+{
652
+ unsigned int i;
653
+ unsigned int pending_nr = revs->pending.nr;
654
+ struct object_array_entry *pending_e = revs->pending.objects;
655
+
656
+ struct object_list *wants = NULL;
657
+ struct object_list *haves = NULL;
658
+
659
+ struct bitmap *wants_bitmap = NULL;
660
+ struct bitmap *haves_bitmap = NULL;
661
+
662
+ if (!bitmap_git.loaded) {
663
+ /* try to open a bitmapped pack, but don't parse it yet
664
+ * because we may not need to use it */
665
+ if (open_pack_bitmap() < 0)
666
+ return -1;
667
+ }
668
+
669
+ for (i = 0; i < pending_nr; ++i) {
670
+ struct object *object = pending_e[i].item;
671
+
672
+ if (object->type == OBJ_NONE)
673
+ parse_object_or_die(object->sha1, NULL);
674
+
675
+ while (object->type == OBJ_TAG) {
676
+ struct tag *tag = (struct tag *) object;
677
+
678
+ if (object->flags & UNINTERESTING)
679
+ object_list_insert(object, &haves);
680
+ else
681
+ object_list_insert(object, &wants);
682
+
683
+ if (!tag->tagged)
684
+ die("bad tag");
685
+ object = parse_object_or_die(tag->tagged->sha1, NULL);
686
+ }
687
+
688
+ if (object->flags & UNINTERESTING)
689
+ object_list_insert(object, &haves);
690
+ else
691
+ object_list_insert(object, &wants);
692
+ }
693
+
694
+ /*
695
+ * if we have a HAVES list, but none of those haves is contained
696
+ * in the packfile that has a bitmap, we don't have anything to
697
+ * optimize here
698
+ */
699
+ if (haves && !in_bitmapped_pack(haves))
700
+ return -1;
701
+
702
+ /* if we don't want anything, we're done here */
703
+ if (!wants)
704
+ return -1;
705
+
706
+ /*
707
+ * now we're going to use bitmaps, so load the actual bitmap entries
708
+ * from disk. this is the point of no return; after this the rev_list
709
+ * becomes invalidated and we must perform the revwalk through bitmaps
710
+ */
711
+ if (!bitmap_git.loaded && load_pack_bitmap() < 0)
712
+ return -1;
713
+
714
+ revs->pending.nr = 0;
715
+ revs->pending.alloc = 0;
716
+ revs->pending.objects = NULL;
717
+
718
+ if (haves) {
719
+ haves_bitmap = find_objects(revs, haves, NULL);
720
+ reset_revision_walk();
721
+
722
+ if (haves_bitmap == NULL)
723
+ die("BUG: failed to perform bitmap walk");
724
+ }
725
+
726
+ wants_bitmap = find_objects(revs, wants, haves_bitmap);
727
+
728
+ if (!wants_bitmap)
729
+ die("BUG: failed to perform bitmap walk");
730
+
731
+ if (haves_bitmap)
732
+ bitmap_and_not(wants_bitmap, haves_bitmap);
733
+
734
+ bitmap_git.result = wants_bitmap;
735
+
736
+ bitmap_free(haves_bitmap);
737
+ return 0;
738
+}
739
+
740
+int reuse_partial_packfile_from_bitmap(struct packed_git **packfile,
741
+ uint32_t *entries,
742
+ off_t *up_to)
743
+{
744
+ /*
745
+ * Reuse the packfile content if we need more than
746
+ * 90% of its objects
747
+ */
748
+ static const double REUSE_PERCENT = 0.9;
749
+
750
+ struct bitmap *result = bitmap_git.result;
751
+ uint32_t reuse_threshold;
752
+ uint32_t i, reuse_objects = 0;
753
+
754
+ assert(result);
755
+
756
+ for (i = 0; i < result->word_alloc; ++i) {
757
+ if (result->words[i] != (eword_t)~0) {
758
+ reuse_objects += ewah_bit_ctz64(~result->words[i]);
759
+ break;
760
+ }
761
+
762
+ reuse_objects += BITS_IN_WORD;
763
+ }
764
+
765
+#ifdef GIT_BITMAP_DEBUG
766
+ {
767
+ const unsigned char *sha1;
768
+ struct revindex_entry *entry;
769
+
770
+ entry = &bitmap_git.reverse_index->revindex[reuse_objects];
771
+ sha1 = nth_packed_object_sha1(bitmap_git.pack, entry->nr);
772
+
773
+ fprintf(stderr, "Failed to reuse at %d (%016llx)\n",
774
+ reuse_objects, result->words[i]);
775
+ fprintf(stderr, " %s\n", sha1_to_hex(sha1));
776
+ }
777
+#endif
778
+
779
+ if (!reuse_objects)
780
+ return -1;
781
+
782
+ if (reuse_objects >= bitmap_git.pack->num_objects) {
783
+ bitmap_git.reuse_objects = *entries = bitmap_git.pack->num_objects;
784
+ *up_to = -1; /* reuse the full pack */
785
+ *packfile = bitmap_git.pack;
786
+ return 0;
787
+ }
788
+
789
+ reuse_threshold = bitmap_popcount(bitmap_git.result) * REUSE_PERCENT;
790
+
791
+ if (reuse_objects < reuse_threshold)
792
+ return -1;
793
+
794
+ bitmap_git.reuse_objects = *entries = reuse_objects;
795
+ *up_to = bitmap_git.reverse_index->revindex[reuse_objects].offset;
796
+ *packfile = bitmap_git.pack;
797
+
798
+ return 0;
799
+}
800
+
801
+void traverse_bitmap_commit_list(show_reachable_fn show_reachable)
802
+{
803
+ assert(bitmap_git.result);
804
+
805
+ show_objects_for_type(bitmap_git.result, bitmap_git.commits,
806
+ OBJ_COMMIT, show_reachable);
807
+ show_objects_for_type(bitmap_git.result, bitmap_git.trees,
808
+ OBJ_TREE, show_reachable);
809
+ show_objects_for_type(bitmap_git.result, bitmap_git.blobs,
810
+ OBJ_BLOB, show_reachable);
811
+ show_objects_for_type(bitmap_git.result, bitmap_git.tags,
812
+ OBJ_TAG, show_reachable);
813
+
814
+ show_extended_objects(bitmap_git.result, show_reachable);
815
+
816
+ bitmap_free(bitmap_git.result);
817
+ bitmap_git.result = NULL;
818
+}
819
+
820
+static uint32_t count_object_type(struct bitmap *objects,
821
+ enum object_type type)
822
+{
823
+ struct eindex *eindex = &bitmap_git.ext_index;
824
+
825
+ uint32_t i = 0, count = 0;
826
+ struct ewah_iterator it;
827
+ eword_t filter;
828
+
829
+ switch (type) {
830
+ case OBJ_COMMIT:
831
+ ewah_iterator_init(&it, bitmap_git.commits);
832
+ break;
833
+
834
+ case OBJ_TREE:
835
+ ewah_iterator_init(&it, bitmap_git.trees);
836
+ break;
837
+
838
+ case OBJ_BLOB:
839
+ ewah_iterator_init(&it, bitmap_git.blobs);
840
+ break;
841
+
842
+ case OBJ_TAG:
843
+ ewah_iterator_init(&it, bitmap_git.tags);
844
+ break;
845
+
846
+ default:
847
+ return 0;
848
+ }
849
+
850
+ while (i < objects->word_alloc && ewah_iterator_next(&filter, &it)) {
851
+ eword_t word = objects->words[i++] & filter;
852
+ count += ewah_bit_popcount64(word);
853
+ }
854
+
855
+ for (i = 0; i < eindex->count; ++i) {
856
+ if (eindex->objects[i]->type == type &&
857
+ bitmap_get(objects, bitmap_git.pack->num_objects + i))
858
+ count++;
859
+ }
860
+
861
+ return count;
862
+}
863
+
864
+void count_bitmap_commit_list(uint32_t *commits, uint32_t *trees,
865
+ uint32_t *blobs, uint32_t *tags)
866
+{
867
+ assert(bitmap_git.result);
868
+
869
+ if (commits)
870
+ *commits = count_object_type(bitmap_git.result, OBJ_COMMIT);
871
+
872
+ if (trees)
873
+ *trees = count_object_type(bitmap_git.result, OBJ_TREE);
874
+
875
+ if (blobs)
876
+ *blobs = count_object_type(bitmap_git.result, OBJ_BLOB);
877
+
878
+ if (tags)
879
+ *tags = count_object_type(bitmap_git.result, OBJ_TAG);
880
+}
881
+
882
+struct bitmap_test_data {
883
+ struct bitmap *base;
884
+ struct progress *prg;
885
+ size_t seen;
886
+};
887
+
888
+static void test_show_object(struct object *object,
889
+ const struct name_path *path,
890
+ const char *last, void *data)
891
+{
892
+ struct bitmap_test_data *tdata = data;
893
+ int bitmap_pos;
894
+
895
+ bitmap_pos = bitmap_position(object->sha1);
896
+ if (bitmap_pos < 0)
897
+ die("Object not in bitmap: %s\n", sha1_to_hex(object->sha1));
898
+
899
+ bitmap_set(tdata->base, bitmap_pos);
900
+ display_progress(tdata->prg, ++tdata->seen);
901
+}
902
+
903
+static void test_show_commit(struct commit *commit, void *data)
904
+{
905
+ struct bitmap_test_data *tdata = data;
906
+ int bitmap_pos;
907
+
908
+ bitmap_pos = bitmap_position(commit->object.sha1);
909
+ if (bitmap_pos < 0)
910
+ die("Object not in bitmap: %s\n", sha1_to_hex(commit->object.sha1));
911
+
912
+ bitmap_set(tdata->base, bitmap_pos);
913
+ display_progress(tdata->prg, ++tdata->seen);
914
+}
915
+
916
+void test_bitmap_walk(struct rev_info *revs)
917
+{
918
+ struct object *root;
919
+ struct bitmap *result = NULL;
920
+ khiter_t pos;
921
+ size_t result_popcnt;
922
+ struct bitmap_test_data tdata;
923
+
924
+ if (prepare_bitmap_git())
925
+ die("failed to load bitmap indexes");
926
+
927
+ if (revs->pending.nr != 1)
928
+ die("you must specify exactly one commit to test");
929
+
930
+ fprintf(stderr, "Bitmap v%d test (%d entries loaded)\n",
931
+ bitmap_git.version, bitmap_git.entry_count);
932
+
933
+ root = revs->pending.objects[0].item;
934
+ pos = kh_get_sha1(bitmap_git.bitmaps, root->sha1);
935
+
936
+ if (pos < kh_end(bitmap_git.bitmaps)) {
937
+ struct stored_bitmap *st = kh_value(bitmap_git.bitmaps, pos);
938
+ struct ewah_bitmap *bm = lookup_stored_bitmap(st);
939
+
940
+ fprintf(stderr, "Found bitmap for %s. %d bits / %08x checksum\n",
941
+ sha1_to_hex(root->sha1), (int)bm->bit_size, ewah_checksum(bm));
942
+
943
+ result = ewah_to_bitmap(bm);
944
+ }
945
+
946
+ if (result == NULL)
947
+ die("Commit %s doesn't have an indexed bitmap", sha1_to_hex(root->sha1));
948
+
949
+ revs->tag_objects = 1;
950
+ revs->tree_objects = 1;
951
+ revs->blob_objects = 1;
952
+
953
+ result_popcnt = bitmap_popcount(result);
954
+
955
+ if (prepare_revision_walk(revs))
956
+ die("revision walk setup failed");
957
+
958
+ tdata.base = bitmap_new();
959
+ tdata.prg = start_progress("Verifying bitmap entries", result_popcnt);
960
+ tdata.seen = 0;
961
+
962
+ traverse_commit_list(revs, &test_show_commit, &test_show_object, &tdata);
963
+
964
+ stop_progress(&tdata.prg);
965
+
966
+ if (bitmap_equals(result, tdata.base))
967
+ fprintf(stderr, "OK!\n");
968
+ else
969
+ fprintf(stderr, "Mismatch!\n");
970
+}