diff options
Diffstat (limited to 'pack-bitmap.c')
-rw-r--r-- | pack-bitmap.c | 137 |
1 files changed, 66 insertions, 71 deletions
diff --git a/pack-bitmap.c b/pack-bitmap.c index ae0b57b950..39bcc16846 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -33,9 +33,6 @@ static struct bitmap_index { /* Packfile to which this bitmap index belongs to */ struct packed_git *pack; - /* reverse index for the packfile */ - struct pack_revindex *reverse_index; - /* * Mark the first `reuse_objects` in the packfile as reused: * they will be sent as-is without using them for repacking @@ -60,7 +57,7 @@ static struct bitmap_index { struct ewah_bitmap *blobs; struct ewah_bitmap *tags; - /* Map from SHA1 -> `stored_bitmap` for all the bitmapped comits */ + /* Map from SHA1 -> `stored_bitmap` for all the bitmapped commits */ khash_sha1 *bitmaps; /* Number of bitmapped commits */ @@ -197,15 +194,24 @@ static struct stored_bitmap *store_bitmap(struct bitmap_index *index, return stored; } -static int load_bitmap_entries_v1(struct bitmap_index *index) +static inline uint32_t read_be32(const unsigned char *buffer, size_t *pos) { - static const size_t MAX_XOR_OFFSET = 160; + uint32_t result = get_be32(buffer + *pos); + (*pos) += sizeof(result); + return result; +} - uint32_t i; - struct stored_bitmap **recent_bitmaps; - struct bitmap_disk_entry *entry; +static inline uint8_t read_u8(const unsigned char *buffer, size_t *pos) +{ + return buffer[(*pos)++]; +} - recent_bitmaps = xcalloc(MAX_XOR_OFFSET, sizeof(struct stored_bitmap)); +#define MAX_XOR_OFFSET 160 + +static int load_bitmap_entries_v1(struct bitmap_index *index) +{ + uint32_t i; + struct stored_bitmap *recent_bitmaps[MAX_XOR_OFFSET] = { NULL }; for (i = 0; i < index->entry_count; ++i) { int xor_offset, flags; @@ -214,15 +220,12 @@ static int load_bitmap_entries_v1(struct bitmap_index *index) uint32_t commit_idx_pos; const unsigned char *sha1; - entry = (struct bitmap_disk_entry *)(index->map + index->map_pos); - index->map_pos += sizeof(struct bitmap_disk_entry); + commit_idx_pos = read_be32(index->map, &index->map_pos); + xor_offset = read_u8(index->map, &index->map_pos); + flags = read_u8(index->map, &index->map_pos); - commit_idx_pos = ntohl(entry->object_pos); sha1 = nth_packed_object_sha1(index->pack, commit_idx_pos); - xor_offset = (int)entry->xor_offset; - flags = (int)entry->flags; - bitmap = read_bitmap_1(index); if (!bitmap) return -1; @@ -244,6 +247,15 @@ static int load_bitmap_entries_v1(struct bitmap_index *index) return 0; } +static char *pack_bitmap_filename(struct packed_git *p) +{ + size_t len; + + if (!strip_suffix(p->pack_name, ".pack", &len)) + die("BUG: pack_name does not end in .pack"); + return xstrfmt("%.*s.bitmap", (int)len, p->pack_name); +} + static int open_pack_bitmap_1(struct packed_git *packfile) { int fd; @@ -254,7 +266,7 @@ static int open_pack_bitmap_1(struct packed_git *packfile) return -1; idx_name = pack_bitmap_filename(packfile); - fd = git_open_noatime(idx_name); + fd = git_open(idx_name); free(idx_name); if (fd < 0) @@ -293,7 +305,7 @@ static int load_pack_bitmap(void) bitmap_git.bitmaps = kh_init_sha1(); bitmap_git.ext_index.positions = kh_init_sha1_pos(); - bitmap_git.reverse_index = revindex_for_pack(bitmap_git.pack); + load_pack_revindex(bitmap_git.pack); if (!(bitmap_git.commits = read_bitmap_1(&bitmap_git)) || !(bitmap_git.trees = read_bitmap_1(&bitmap_git)) || @@ -314,20 +326,6 @@ failed: return -1; } -char *pack_bitmap_filename(struct packed_git *p) -{ - char *idx_name; - int len; - - len = strlen(p->pack_name) - strlen(".pack"); - idx_name = xmalloc(len + strlen(".bitmap") + 1); - - memcpy(idx_name, p->pack_name, len); - memcpy(idx_name + len, ".bitmap", strlen(".bitmap") + 1); - - return idx_name; -} - static int open_pack_bitmap(void) { struct packed_git *p; @@ -379,7 +377,7 @@ static inline int bitmap_position_packfile(const unsigned char *sha1) if (!offset) return -1; - return find_revindex_position(bitmap_git.reverse_index, offset); + return find_revindex_position(bitmap_git.pack, offset); } static int bitmap_position(const unsigned char *sha1) @@ -396,14 +394,12 @@ static int ext_index_add_object(struct object *object, const char *name) int hash_ret; int bitmap_pos; - hash_pos = kh_put_sha1_pos(eindex->positions, object->sha1, &hash_ret); + hash_pos = kh_put_sha1_pos(eindex->positions, object->oid.hash, &hash_ret); if (hash_ret > 0) { if (eindex->count >= eindex->alloc) { eindex->alloc = (eindex->alloc + 16) * 3 / 2; - eindex->objects = xrealloc(eindex->objects, - eindex->alloc * sizeof(struct object *)); - eindex->hashes = xrealloc(eindex->hashes, - eindex->alloc * sizeof(uint32_t)); + REALLOC_ARRAY(eindex->objects, eindex->alloc); + REALLOC_ARRAY(eindex->hashes, eindex->alloc); } bitmap_pos = eindex->count; @@ -418,19 +414,15 @@ static int ext_index_add_object(struct object *object, const char *name) return bitmap_pos + bitmap_git.pack->num_objects; } -static void show_object(struct object *object, const struct name_path *path, - const char *last, void *data) +static void show_object(struct object *object, const char *name, void *data) { struct bitmap *base = data; int bitmap_pos; - bitmap_pos = bitmap_position(object->sha1); + bitmap_pos = bitmap_position(object->oid.hash); - if (bitmap_pos < 0) { - char *name = path_name(path, last); + if (bitmap_pos < 0) bitmap_pos = ext_index_add_object(object, name); - free(name); - } bitmap_set(base, bitmap_pos); } @@ -467,11 +459,11 @@ static int should_include(struct commit *commit, void *_data) struct include_data *data = _data; int bitmap_pos; - bitmap_pos = bitmap_position(commit->object.sha1); + bitmap_pos = bitmap_position(commit->object.oid.hash); if (bitmap_pos < 0) bitmap_pos = ext_index_add_object((struct object *)commit, NULL); - if (!add_to_include_set(data, commit->object.sha1, bitmap_pos)) { + if (!add_to_include_set(data, commit->object.oid.hash, bitmap_pos)) { struct commit_list *parent = commit->parents; while (parent) { @@ -507,7 +499,7 @@ static struct bitmap *find_objects(struct rev_info *revs, roots = roots->next; if (object->type == OBJ_COMMIT) { - khiter_t pos = kh_get_sha1(bitmap_git.bitmaps, object->sha1); + khiter_t pos = kh_get_sha1(bitmap_git.bitmaps, object->oid.hash); if (pos < kh_end(bitmap_git.bitmaps)) { struct stored_bitmap *st = kh_value(bitmap_git.bitmaps, pos); @@ -549,7 +541,7 @@ static struct bitmap *find_objects(struct rev_info *revs, int pos; roots = roots->next; - pos = bitmap_position(object->sha1); + pos = bitmap_position(object->oid.hash); if (pos < 0 || base == NULL || !bitmap_get(base, pos)) { object->flags &= ~UNINTERESTING; @@ -594,7 +586,7 @@ static void show_extended_objects(struct bitmap *objects, continue; obj = eindex->objects[i]; - show_reach(obj->sha1, obj->type, 0, eindex->hashes[i], NULL, 0); + show_reach(obj->oid.hash, obj->type, 0, eindex->hashes[i], NULL, 0); } } @@ -618,7 +610,7 @@ static void show_objects_for_type( while (i < objects->word_alloc && ewah_iterator_next(&filter, &it)) { eword_t word = objects->words[i] & filter; - for (offset = 0; offset < BITS_IN_WORD; ++offset) { + for (offset = 0; offset < BITS_IN_EWORD; ++offset) { const unsigned char *sha1; struct revindex_entry *entry; uint32_t hash = 0; @@ -631,7 +623,7 @@ static void show_objects_for_type( if (pos + offset < bitmap_git.reuse_objects) continue; - entry = &bitmap_git.reverse_index->revindex[pos + offset]; + entry = &bitmap_git.pack->revindex[pos + offset]; sha1 = nth_packed_object_sha1(bitmap_git.pack, entry->nr); if (bitmap_git.hashes) @@ -640,7 +632,7 @@ static void show_objects_for_type( show_reach(sha1, object_type, 0, hash, bitmap_git.pack, entry->offset); } - pos += BITS_IN_WORD; + pos += BITS_IN_EWORD; i++; } } @@ -651,7 +643,7 @@ static int in_bitmapped_pack(struct object_list *roots) struct object *object = roots->item; roots = roots->next; - if (find_pack_entry_one(object->sha1, bitmap_git.pack) > 0) + if (find_pack_entry_one(object->oid.hash, bitmap_git.pack) > 0) return 1; } @@ -681,7 +673,7 @@ int prepare_bitmap_walk(struct rev_info *revs) struct object *object = pending_e[i].item; if (object->type == OBJ_NONE) - parse_object_or_die(object->sha1, NULL); + parse_object_or_die(object->oid.hash, NULL); while (object->type == OBJ_TAG) { struct tag *tag = (struct tag *) object; @@ -693,7 +685,7 @@ int prepare_bitmap_walk(struct rev_info *revs) if (!tag->tagged) die("bad tag"); - object = parse_object_or_die(tag->tagged->sha1, NULL); + object = parse_object_or_die(tag->tagged->oid.hash, NULL); } if (object->flags & UNINTERESTING) @@ -727,8 +719,10 @@ int prepare_bitmap_walk(struct rev_info *revs) revs->pending.objects = NULL; if (haves) { + revs->ignore_missing_links = 1; haves_bitmap = find_objects(revs, haves, NULL); reset_revision_walk(); + revs->ignore_missing_links = 0; if (haves_bitmap == NULL) die("BUG: failed to perform bitmap walk"); @@ -770,7 +764,7 @@ int reuse_partial_packfile_from_bitmap(struct packed_git **packfile, break; } - reuse_objects += BITS_IN_WORD; + reuse_objects += BITS_IN_EWORD; } #ifdef GIT_BITMAP_DEBUG @@ -803,7 +797,7 @@ int reuse_partial_packfile_from_bitmap(struct packed_git **packfile, return -1; bitmap_git.reuse_objects = *entries = reuse_objects; - *up_to = bitmap_git.reverse_index->revindex[reuse_objects].offset; + *up_to = bitmap_git.pack->revindex[reuse_objects].offset; *packfile = bitmap_git.pack; return 0; @@ -896,16 +890,15 @@ struct bitmap_test_data { size_t seen; }; -static void test_show_object(struct object *object, - const struct name_path *path, - const char *last, void *data) +static void test_show_object(struct object *object, const char *name, + void *data) { struct bitmap_test_data *tdata = data; int bitmap_pos; - bitmap_pos = bitmap_position(object->sha1); + bitmap_pos = bitmap_position(object->oid.hash); if (bitmap_pos < 0) - die("Object not in bitmap: %s\n", sha1_to_hex(object->sha1)); + die("Object not in bitmap: %s\n", oid_to_hex(&object->oid)); bitmap_set(tdata->base, bitmap_pos); display_progress(tdata->prg, ++tdata->seen); @@ -916,9 +909,9 @@ static void test_show_commit(struct commit *commit, void *data) struct bitmap_test_data *tdata = data; int bitmap_pos; - bitmap_pos = bitmap_position(commit->object.sha1); + bitmap_pos = bitmap_position(commit->object.oid.hash); if (bitmap_pos < 0) - die("Object not in bitmap: %s\n", sha1_to_hex(commit->object.sha1)); + die("Object not in bitmap: %s\n", oid_to_hex(&commit->object.oid)); bitmap_set(tdata->base, bitmap_pos); display_progress(tdata->prg, ++tdata->seen); @@ -942,20 +935,20 @@ void test_bitmap_walk(struct rev_info *revs) bitmap_git.version, bitmap_git.entry_count); root = revs->pending.objects[0].item; - pos = kh_get_sha1(bitmap_git.bitmaps, root->sha1); + pos = kh_get_sha1(bitmap_git.bitmaps, root->oid.hash); if (pos < kh_end(bitmap_git.bitmaps)) { struct stored_bitmap *st = kh_value(bitmap_git.bitmaps, pos); struct ewah_bitmap *bm = lookup_stored_bitmap(st); fprintf(stderr, "Found bitmap for %s. %d bits / %08x checksum\n", - sha1_to_hex(root->sha1), (int)bm->bit_size, ewah_checksum(bm)); + oid_to_hex(&root->oid), (int)bm->bit_size, ewah_checksum(bm)); result = ewah_to_bitmap(bm); } if (result == NULL) - die("Commit %s doesn't have an indexed bitmap", sha1_to_hex(root->sha1)); + die("Commit %s doesn't have an indexed bitmap", oid_to_hex(&root->oid)); revs->tag_objects = 1; revs->tree_objects = 1; @@ -978,6 +971,8 @@ void test_bitmap_walk(struct rev_info *revs) fprintf(stderr, "OK!\n"); else fprintf(stderr, "Mismatch!\n"); + + bitmap_free(result); } static int rebuild_bitmap(uint32_t *reposition, @@ -993,7 +988,7 @@ static int rebuild_bitmap(uint32_t *reposition, while (ewah_iterator_next(&word, &it)) { uint32_t offset, bit_pos; - for (offset = 0; offset < BITS_IN_WORD; ++offset) { + for (offset = 0; offset < BITS_IN_EWORD; ++offset) { if ((word >> offset) == 0) break; @@ -1006,7 +1001,7 @@ static int rebuild_bitmap(uint32_t *reposition, return -1; } - pos += BITS_IN_WORD; + pos += BITS_IN_EWORD; } return 0; } @@ -1035,7 +1030,7 @@ int rebuild_existing_bitmaps(struct packing_data *mapping, struct revindex_entry *entry; struct object_entry *oe; - entry = &bitmap_git.reverse_index->revindex[i]; + entry = &bitmap_git.pack->revindex[i]; sha1 = nth_packed_object_sha1(bitmap_git.pack, entry->nr); oe = packlist_find(mapping, sha1, NULL); |