Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-pack-index cleanups #9

Closed
wants to merge 10 commits into from
2 changes: 1 addition & 1 deletion builtin/count-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
struct strbuf pack_buf = STRBUF_INIT;
struct strbuf garbage_buf = STRBUF_INIT;

for (p = get_packed_git(the_repository); p; p = p->next) {
for (p = get_all_packs(the_repository); p; p = p->next) {
if (!p->pack_local)
continue;
if (open_pack_index(p))
Expand Down
4 changes: 2 additions & 2 deletions builtin/fsck.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
struct progress *progress = NULL;

if (show_progress) {
for (p = get_packed_git(the_repository); p;
for (p = get_all_packs(the_repository); p;
p = p->next) {
if (open_pack_index(p))
continue;
Expand All @@ -749,7 +749,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)

progress = start_progress(_("Checking objects"), total);
}
for (p = get_packed_git(the_repository); p;
for (p = get_all_packs(the_repository); p;
p = p->next) {
/* verify gives error messages itself */
if (verify_pack(p, fsck_obj_buffer,
Expand Down
4 changes: 2 additions & 2 deletions builtin/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ static struct packed_git *find_base_packs(struct string_list *packs,
{
struct packed_git *p, *base = NULL;

for (p = get_packed_git(the_repository); p; p = p->next) {
for (p = get_all_packs(the_repository); p; p = p->next) {
if (!p->pack_local)
continue;
if (limit) {
Expand All @@ -208,7 +208,7 @@ static int too_many_packs(void)
if (gc_auto_pack_limit <= 0)
return 0;

for (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) {
for (cnt = 0, p = get_all_packs(the_repository); p; p = p->next) {
if (!p->pack_local)
continue;
if (p->pack_keep)
Expand Down
16 changes: 8 additions & 8 deletions builtin/multi-pack-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ int cmd_multi_pack_index(int argc, const char **argv,
opts.object_dir = get_object_directory();

if (argc == 0)
goto usage;
usage_with_options(builtin_multi_pack_index_usage,
builtin_multi_pack_index_options);

if (!strcmp(argv[0], "write")) {
if (argc > 1)
goto usage;
if (argc > 1) {
die(_("too many arguments"));
return 1;
}

if (!strcmp(argv[0], "write"))
return write_midx_file(opts.object_dir);
}

usage:
usage_with_options(builtin_multi_pack_index_usage,
builtin_multi_pack_index_options);
die(_("unrecognized verb: %s"), argv[0]);
}
42 changes: 35 additions & 7 deletions builtin/pack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "packfile.h"
#include "object-store.h"
#include "dir.h"
#include "midx.h"

#define IN_PACK(obj) oe_in_pack(&to_pack, obj)
#define SIZE(obj) oe_size(&to_pack, obj)
Expand Down Expand Up @@ -1034,6 +1035,7 @@ static int want_object_in_pack(const struct object_id *oid,
{
int want;
struct list_head *pos;
struct multi_pack_index *m;

if (!exclude && local && has_loose_object_nonlocal(oid))
return 0;
Expand All @@ -1048,6 +1050,32 @@ static int want_object_in_pack(const struct object_id *oid,
if (want != -1)
return want;
}

for (m = get_multi_pack_index(the_repository); m; m = m->next) {
struct pack_entry e;
if (fill_midx_entry(oid, &e, m)) {
struct packed_git *p = e.p;
off_t offset;

if (p == *found_pack)
offset = *found_offset;
else
offset = find_pack_entry_one(oid->hash, p);

if (offset) {
if (!*found_pack) {
if (!is_pack_valid(p))
continue;
*found_offset = offset;
*found_pack = p;
}
want = want_found_object(exclude, p);
if (want != -1)
return want;
}
}
}

list_for_each(pos, get_packed_git_mru(the_repository)) {
struct packed_git *p = list_entry(pos, struct packed_git, mru);
off_t offset;
Expand Down Expand Up @@ -2784,7 +2812,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)

memset(&in_pack, 0, sizeof(in_pack));

for (p = get_packed_git(the_repository); p; p = p->next) {
for (p = get_all_packs(the_repository); p; p = p->next) {
struct object_id oid;
struct object *o;

Expand Down Expand Up @@ -2848,7 +2876,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
struct packed_git *p;

p = (last_found != (void *)1) ? last_found :
get_packed_git(the_repository);
get_all_packs(the_repository);

while (p) {
if ((!p->pack_local || p->pack_keep ||
Expand All @@ -2858,7 +2886,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
return 1;
}
if (p == last_found)
p = get_packed_git(the_repository);
p = get_all_packs(the_repository);
else
p = p->next;
if (p == last_found)
Expand Down Expand Up @@ -2894,7 +2922,7 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
uint32_t i;
struct object_id oid;

for (p = get_packed_git(the_repository); p; p = p->next) {
for (p = get_all_packs(the_repository); p; p = p->next) {
if (!p->pack_local || p->pack_keep || p->pack_keep_in_core)
continue;

Expand Down Expand Up @@ -3041,7 +3069,7 @@ static void add_extra_kept_packs(const struct string_list *names)
if (!names->nr)
return;

for (p = get_packed_git(the_repository); p; p = p->next) {
for (p = get_all_packs(the_repository); p; p = p->next) {
const char *name = basename(p->pack_name);
int i;

Expand Down Expand Up @@ -3314,7 +3342,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
add_extra_kept_packs(&keep_pack_list);
if (ignore_packed_keep_on_disk) {
struct packed_git *p;
for (p = get_packed_git(the_repository); p; p = p->next)
for (p = get_all_packs(the_repository); p; p = p->next)
if (p->pack_local && p->pack_keep)
break;
if (!p) /* no keep-able packs found */
Expand All @@ -3327,7 +3355,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
* it also covers non-local objects
*/
struct packed_git *p;
for (p = get_packed_git(the_repository); p; p = p->next) {
for (p = get_all_packs(the_repository); p; p = p->next) {
if (!p->pack_local) {
have_non_local_packs = 1;
break;
Expand Down
4 changes: 2 additions & 2 deletions builtin/pack-redundant.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ static struct pack_list * add_pack(struct packed_git *p)

static struct pack_list * add_pack_file(const char *filename)
{
struct packed_git *p = get_packed_git(the_repository);
struct packed_git *p = get_all_packs(the_repository);

if (strlen(filename) < 40)
die("Bad pack filename: %s", filename);
Expand All @@ -592,7 +592,7 @@ static struct pack_list * add_pack_file(const char *filename)

static void load_all(void)
{
struct packed_git *p = get_packed_git(the_repository);
struct packed_git *p = get_all_packs(the_repository);

while (p) {
add_pack(p);
Expand Down
1 change: 1 addition & 0 deletions builtin/repack.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
if (!no_update_server_info)
update_server_info(0);
remove_temporary_files();
write_midx_file(get_object_directory());
string_list_clear(&names, 0);
string_list_clear(&rollback, 0);
string_list_clear(&existing_packs, 0);
Expand Down
4 changes: 2 additions & 2 deletions fast-import.c
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ static int store_object(
duplicate_count_by_type[type]++;
return 1;
} else if (find_sha1_pack(oid.hash,
get_packed_git(the_repository))) {
get_all_packs(the_repository))) {
e->type = type;
e->pack_id = MAX_PACK_ID;
e->idx.offset = 1; /* just not zero! */
Expand Down Expand Up @@ -1266,7 +1266,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
truncate_pack(&checkpoint);

} else if (find_sha1_pack(oid.hash,
get_packed_git(the_repository))) {
get_all_packs(the_repository))) {
e->type = OBJ_BLOB;
e->pack_id = MAX_PACK_ID;
e->idx.offset = 1; /* just not zero! */
Expand Down
4 changes: 2 additions & 2 deletions http-backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,13 +523,13 @@ static void get_info_packs(struct strbuf *hdr, char *arg)
size_t cnt = 0;

select_getanyfile(hdr);
for (p = get_packed_git(the_repository); p; p = p->next) {
for (p = get_all_packs(the_repository); p; p = p->next) {
if (p->pack_local)
cnt++;
}

strbuf_grow(&buf, cnt * 53 + 2);
for (p = get_packed_git(the_repository); p; p = p->next) {
for (p = get_all_packs(the_repository); p; p = p->next) {
if (p->pack_local)
strbuf_addf(&buf, "P %s\n", p->pack_name + objdirlen + 6);
}
Expand Down
37 changes: 22 additions & 15 deletions midx.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static char *get_midx_filename(const char *object_dir)
return xstrfmt("%s/pack/multi-pack-index", object_dir);
}

struct multi_pack_index *load_multi_pack_index(const char *object_dir)
struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local)
{
struct multi_pack_index *m = NULL;
int fd;
Expand Down Expand Up @@ -73,6 +73,7 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir)
m->fd = fd;
m->data = midx_map;
m->data_len = midx_size;
m->local = local;

m->signature = get_be32(m->data);
if (m->signature != MIDX_SIGNATURE) {
Expand Down Expand Up @@ -196,7 +197,7 @@ static void close_midx(struct multi_pack_index *m)
FREE_AND_NULL(m->pack_names);
}

static int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id)
int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id)
{
struct strbuf pack_name = STRBUF_INIT;

Expand All @@ -209,7 +210,7 @@ static int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id)
strbuf_addf(&pack_name, "%s/pack/%s", m->object_dir,
m->pack_names[pack_int_id]);

m->packs[pack_int_id] = add_packed_git(pack_name.buf, pack_name.len, 1);
m->packs[pack_int_id] = add_packed_git(pack_name.buf, pack_name.len, m->local);
strbuf_release(&pack_name);
return !m->packs[pack_int_id];
}
Expand Down Expand Up @@ -279,6 +280,16 @@ static int nth_midxed_pack_entry(struct multi_pack_index *m, struct pack_entry *
if (!is_pack_valid(p))
return 0;

if (p->num_bad_objects) {
uint32_t i;
struct object_id oid;
nth_midxed_object_oid(&oid, m, pos);
for (i = 0; i < p->num_bad_objects; i++)
if (!hashcmp(oid.hash,
p->bad_object_sha1 + the_hash_algo->rawsz * i))
return 0;
}

e->offset = nth_midxed_offset(m, pos);
e->p = p;

Expand Down Expand Up @@ -318,24 +329,20 @@ int midx_contains_pack(struct multi_pack_index *m, const char *idx_name)
return 0;
}

int prepare_multi_pack_index_one(struct repository *r, const char *object_dir)
int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local)
{
struct multi_pack_index *m = r->objects->multi_pack_index;
struct multi_pack_index *m;
struct multi_pack_index *m_search;
int config_value;

if (repo_config_get_bool(r, "core.multipackindex", &config_value) ||
!config_value)
return 0;

for (m_search = m; m_search; m_search = m_search->next)
for (m_search = r->objects->multi_pack_index; m_search; m_search = m_search->next)
if (!strcmp(object_dir, m_search->object_dir))
return 1;

r->objects->multi_pack_index = load_multi_pack_index(object_dir);
m = load_multi_pack_index(object_dir, local);

if (r->objects->multi_pack_index) {
r->objects->multi_pack_index->next = m;
if (m) {
m->next = r->objects->multi_pack_index;
r->objects->multi_pack_index = m;
return 1;
}

Expand Down Expand Up @@ -746,7 +753,7 @@ int write_midx_file(const char *object_dir)
midx_name);
}

packs.m = load_multi_pack_index(object_dir);
packs.m = load_multi_pack_index(object_dir, 1);

packs.nr = 0;
packs.alloc_list = packs.m ? packs.m->num_packs : 16;
Expand Down
7 changes: 5 additions & 2 deletions midx.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ struct multi_pack_index {
uint32_t num_packs;
uint32_t num_objects;

int local;

const unsigned char *chunk_pack_names;
const uint32_t *chunk_oid_fanout;
const unsigned char *chunk_oid_lookup;
Expand All @@ -29,14 +31,15 @@ struct multi_pack_index {
char object_dir[FLEX_ARRAY];
};

struct multi_pack_index *load_multi_pack_index(const char *object_dir);
struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local);
int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id);
int bsearch_midx(const struct object_id *oid, struct multi_pack_index *m, uint32_t *result);
struct object_id *nth_midxed_object_oid(struct object_id *oid,
struct multi_pack_index *m,
uint32_t n);
int fill_midx_entry(const struct object_id *oid, struct pack_entry *e, struct multi_pack_index *m);
int midx_contains_pack(struct multi_pack_index *m, const char *idx_name);
int prepare_multi_pack_index_one(struct repository *r, const char *object_dir);
int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local);

int write_midx_file(const char *object_dir);
void clear_midx_file(const char *object_dir);
Expand Down
6 changes: 6 additions & 0 deletions object-store.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ struct raw_object_store {
/* A most-recently-used ordered version of the packed_git list. */
struct list_head packed_git_mru;

/*
* A linked list containing all packfiles, starting with those
* contained in the multi_pack_index.
*/
struct packed_git *all_packs;

/*
* A fast, rough count of the number of objects in the repository.
* These two fields are not meant for direct access. Use
Expand Down
2 changes: 1 addition & 1 deletion pack-bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ static int open_pack_bitmap(struct bitmap_index *bitmap_git)

assert(!bitmap_git->map && !bitmap_git->loaded);

for (p = get_packed_git(the_repository); p; p = p->next) {
for (p = get_all_packs(the_repository); p; p = p->next) {
if (open_pack_bitmap_1(bitmap_git, p) == 0)
ret = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion pack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ static void prepare_in_pack_by_idx(struct packing_data *pdata)
* (i.e. in_pack_idx also zero) should return NULL.
*/
mapping[cnt++] = NULL;
for (p = get_packed_git(the_repository); p; p = p->next, cnt++) {
for (p = get_all_packs(the_repository); p; p = p->next, cnt++) {
if (cnt == nr) {
free(mapping);
return;
Expand Down
Loading