summaryrefslogtreecommitdiff
path: root/pack-bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'pack-bitmap.c')
-rw-r--r--pack-bitmap.c123
1 files changed, 86 insertions, 37 deletions
diff --git a/pack-bitmap.c b/pack-bitmap.c
index ac6d62b980..d14421ee20 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -17,7 +17,7 @@
#include "packfile.h"
#include "repository.h"
#include "trace2.h"
-#include "object-store.h"
+#include "odb.h"
#include "list-objects-filter-options.h"
#include "midx.h"
#include "config.h"
@@ -31,6 +31,7 @@ struct stored_bitmap {
struct object_id oid;
struct ewah_bitmap *root;
struct stored_bitmap *xor;
+ size_t map_pos;
int flags;
};
@@ -314,13 +315,14 @@ static struct stored_bitmap *store_bitmap(struct bitmap_index *index,
struct ewah_bitmap *root,
const struct object_id *oid,
struct stored_bitmap *xor_with,
- int flags)
+ int flags, size_t map_pos)
{
struct stored_bitmap *stored;
khiter_t hash_pos;
int ret;
stored = xmalloc(sizeof(struct stored_bitmap));
+ stored->map_pos = map_pos;
stored->root = root;
stored->xor = xor_with;
stored->flags = flags;
@@ -376,10 +378,12 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
struct stored_bitmap *xor_bitmap = NULL;
uint32_t commit_idx_pos;
struct object_id oid;
+ size_t entry_map_pos;
if (index->map_size - index->map_pos < 6)
return error(_("corrupt ewah bitmap: truncated header for entry %d"), i);
+ entry_map_pos = index->map_pos;
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);
@@ -402,8 +406,9 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
if (!bitmap)
return -1;
- recent_bitmaps[i % MAX_XOR_OFFSET] = store_bitmap(
- index, bitmap, &oid, xor_bitmap, flags);
+ recent_bitmaps[i % MAX_XOR_OFFSET] =
+ store_bitmap(index, bitmap, &oid, xor_bitmap, flags,
+ entry_map_pos);
}
return 0;
@@ -630,41 +635,28 @@ static int load_bitmap(struct repository *r, struct bitmap_index *bitmap_git,
bitmap_git->ext_index.positions = kh_init_oid_pos();
if (load_reverse_index(r, bitmap_git))
- goto failed;
+ return -1;
if (!(bitmap_git->commits = read_bitmap_1(bitmap_git)) ||
!(bitmap_git->trees = read_bitmap_1(bitmap_git)) ||
!(bitmap_git->blobs = read_bitmap_1(bitmap_git)) ||
!(bitmap_git->tags = read_bitmap_1(bitmap_git)))
- goto failed;
+ return -1;
if (!bitmap_git->table_lookup && load_bitmap_entries_v1(bitmap_git) < 0)
- goto failed;
+ return -1;
if (bitmap_git->base) {
if (!bitmap_is_midx(bitmap_git))
BUG("non-MIDX bitmap has non-NULL base bitmap index");
if (load_bitmap(r, bitmap_git->base, 1) < 0)
- goto failed;
+ return -1;
}
if (!recursing)
load_all_type_bitmaps(bitmap_git);
return 0;
-
-failed:
- munmap(bitmap_git->map, bitmap_git->map_size);
- bitmap_git->map = NULL;
- bitmap_git->map_size = 0;
-
- kh_destroy_oid_map(bitmap_git->bitmaps);
- bitmap_git->bitmaps = NULL;
-
- kh_destroy_oid_pos(bitmap_git->ext_index.positions);
- bitmap_git->ext_index.positions = NULL;
-
- return -1;
}
static int open_pack_bitmap(struct repository *r,
@@ -691,13 +683,15 @@ static int open_pack_bitmap(struct repository *r,
static int open_midx_bitmap(struct repository *r,
struct bitmap_index *bitmap_git)
{
+ struct odb_source *source;
int ret = -1;
- struct multi_pack_index *midx;
assert(!bitmap_git->map);
- for (midx = get_multi_pack_index(r); midx; midx = midx->next) {
- if (!open_midx_bitmap_1(bitmap_git, midx))
+ odb_prepare_alternates(r->objects);
+ for (source = r->objects->sources; source; source = source->next) {
+ struct multi_pack_index *midx = get_multi_pack_index(source);
+ if (midx && !open_midx_bitmap_1(bitmap_git, midx))
ret = 0;
}
return ret;
@@ -882,6 +876,7 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
int xor_flags;
khiter_t hash_pos;
struct bitmap_lookup_table_xor_item *xor_item;
+ size_t entry_map_pos;
if (is_corrupt)
return NULL;
@@ -941,6 +936,7 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
goto corrupt;
}
+ entry_map_pos = bitmap_git->map_pos;
bitmap_git->map_pos += sizeof(uint32_t) + sizeof(uint8_t);
xor_flags = read_u8(bitmap_git->map, &bitmap_git->map_pos);
bitmap = read_bitmap_1(bitmap_git);
@@ -948,7 +944,8 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
if (!bitmap)
goto corrupt;
- xor_bitmap = store_bitmap(bitmap_git, bitmap, &xor_item->oid, xor_bitmap, xor_flags);
+ xor_bitmap = store_bitmap(bitmap_git, bitmap, &xor_item->oid,
+ xor_bitmap, xor_flags, entry_map_pos);
xor_items_nr--;
}
@@ -982,6 +979,7 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
* Instead, we can skip ahead and immediately read the flags and
* ewah bitmap.
*/
+ entry_map_pos = bitmap_git->map_pos;
bitmap_git->map_pos += sizeof(uint32_t) + sizeof(uint8_t);
flags = read_u8(bitmap_git->map, &bitmap_git->map_pos);
bitmap = read_bitmap_1(bitmap_git);
@@ -989,7 +987,8 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
if (!bitmap)
goto corrupt;
- return store_bitmap(bitmap_git, bitmap, oid, xor_bitmap, flags);
+ return store_bitmap(bitmap_git, bitmap, oid, xor_bitmap, flags,
+ entry_map_pos);
corrupt:
free(xor_items);
@@ -1363,8 +1362,8 @@ static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git,
bitmap_set(roots_bitmap, pos);
}
- if (!cascade_pseudo_merges_1(bitmap_git, cb.base, roots_bitmap))
- bitmap_free(roots_bitmap);
+ cascade_pseudo_merges_1(bitmap_git, cb.base, roots_bitmap);
+ bitmap_free(roots_bitmap);
}
/*
@@ -1868,8 +1867,8 @@ static unsigned long get_size_by_pos(struct bitmap_index *bitmap_git,
size_t eindex_pos = pos - bitmap_num_objects_total(bitmap_git);
struct eindex *eindex = &bitmap_git->ext_index;
struct object *obj = eindex->objects[eindex_pos];
- if (oid_object_info_extended(bitmap_repo(bitmap_git), &obj->oid,
- &oi, 0) < 0)
+ if (odb_read_object_info_extended(bitmap_repo(bitmap_git)->objects, &obj->oid,
+ &oi, 0) < 0)
die(_("unable to get size of %s"), oid_to_hex(&obj->oid));
}
@@ -2852,8 +2851,9 @@ int test_bitmap_commits(struct repository *r)
die(_("failed to load bitmap indexes"));
/*
- * As this function is only used to print bitmap selected
- * commits, we don't have to read the commit table.
+ * Since this function needs to print the bitmapped
+ * commits, bypass the commit lookup table (if one exists)
+ * by forcing the bitmap to eagerly load its entries.
*/
if (bitmap_git->table_lookup) {
if (load_bitmap_entries_v1(bitmap_git) < 0)
@@ -2869,6 +2869,48 @@ int test_bitmap_commits(struct repository *r)
return 0;
}
+int test_bitmap_commits_with_offset(struct repository *r)
+{
+ struct object_id oid;
+ struct stored_bitmap *stored;
+ struct bitmap_index *bitmap_git;
+ size_t commit_idx_pos_map_pos, xor_offset_map_pos, flag_map_pos,
+ ewah_bitmap_map_pos;
+
+ bitmap_git = prepare_bitmap_git(r);
+ if (!bitmap_git)
+ die(_("failed to load bitmap indexes"));
+
+ /*
+ * Since this function needs to know the position of each individual
+ * bitmap, bypass the commit lookup table (if one exists) by forcing
+ * the bitmap to eagerly load its entries.
+ */
+ if (bitmap_git->table_lookup) {
+ if (load_bitmap_entries_v1(bitmap_git) < 0)
+ die(_("failed to load bitmap indexes"));
+ }
+
+ kh_foreach (bitmap_git->bitmaps, oid, stored, {
+ commit_idx_pos_map_pos = stored->map_pos;
+ xor_offset_map_pos = stored->map_pos + sizeof(uint32_t);
+ flag_map_pos = xor_offset_map_pos + sizeof(uint8_t);
+ ewah_bitmap_map_pos = flag_map_pos + sizeof(uint8_t);
+
+ printf_ln("%s %"PRIuMAX" %"PRIuMAX" %"PRIuMAX" %"PRIuMAX,
+ oid_to_hex(&oid),
+ (uintmax_t)commit_idx_pos_map_pos,
+ (uintmax_t)xor_offset_map_pos,
+ (uintmax_t)flag_map_pos,
+ (uintmax_t)ewah_bitmap_map_pos);
+ })
+ ;
+
+ free_bitmap_index(bitmap_git);
+
+ return 0;
+}
+
int test_bitmap_hashes(struct repository *r)
{
struct bitmap_index *bitmap_git = prepare_bitmap_git(r);
@@ -3220,8 +3262,8 @@ static off_t get_disk_usage_for_extended(struct bitmap_index *bitmap_git)
i)))
continue;
- if (oid_object_info_extended(bitmap_repo(bitmap_git), &obj->oid,
- &oi, 0) < 0)
+ if (odb_read_object_info_extended(bitmap_repo(bitmap_git)->objects,
+ &obj->oid, &oi, 0) < 0)
die(_("unable to get disk usage of '%s'"),
oid_to_hex(&obj->oid));
@@ -3305,11 +3347,18 @@ static int verify_bitmap_file(const struct git_hash_algo *algop,
int verify_bitmap_files(struct repository *r)
{
+ struct odb_source *source;
int res = 0;
- for (struct multi_pack_index *m = get_multi_pack_index(r);
- m; m = m->next) {
- char *midx_bitmap_name = midx_bitmap_filename(m);
+ odb_prepare_alternates(r->objects);
+ for (source = r->objects->sources; source; source = source->next) {
+ struct multi_pack_index *m = get_multi_pack_index(source);
+ char *midx_bitmap_name;
+
+ if (!m)
+ continue;
+
+ midx_bitmap_name = midx_bitmap_filename(m);
res |= verify_bitmap_file(r->hash_algo, midx_bitmap_name);
free(midx_bitmap_name);
}