Merge branch 'sb/object-store'
Refactoring the internal global data structure to make it possible to open multiple repositories, work with and then close them. Rerolled by Duy on top of a separate preliminary clean-up topic. The resulting structure of the topics looked very sensible. * sb/object-store: (27 commits) sha1_file: allow sha1_loose_object_info to handle arbitrary repositories sha1_file: allow map_sha1_file to handle arbitrary repositories sha1_file: allow map_sha1_file_1 to handle arbitrary repositories sha1_file: allow open_sha1_file to handle arbitrary repositories sha1_file: allow stat_sha1_file to handle arbitrary repositories sha1_file: allow sha1_file_name to handle arbitrary repositories sha1_file: add repository argument to sha1_loose_object_info sha1_file: add repository argument to map_sha1_file sha1_file: add repository argument to map_sha1_file_1 sha1_file: add repository argument to open_sha1_file sha1_file: add repository argument to stat_sha1_file sha1_file: add repository argument to sha1_file_name sha1_file: allow prepare_alt_odb to handle arbitrary repositories sha1_file: allow link_alt_odb_entries to handle arbitrary repositories sha1_file: add repository argument to prepare_alt_odb sha1_file: add repository argument to link_alt_odb_entries sha1_file: add repository argument to read_info_alternates sha1_file: add repository argument to link_alt_odb_entry sha1_file: add raw_object_store argument to alt_odb_usable pack: move approximate object count to object store ...
This commit is contained in:
77
packfile.c
77
packfile.c
@ -1,6 +1,7 @@
|
||||
#include "cache.h"
|
||||
#include "list.h"
|
||||
#include "pack.h"
|
||||
#include "repository.h"
|
||||
#include "dir.h"
|
||||
#include "mergesort.h"
|
||||
#include "packfile.h"
|
||||
@ -13,6 +14,7 @@
|
||||
#include "tag.h"
|
||||
#include "tree-walk.h"
|
||||
#include "tree.h"
|
||||
#include "object-store.h"
|
||||
|
||||
char *odb_pack_name(struct strbuf *buf,
|
||||
const unsigned char *sha1,
|
||||
@ -44,8 +46,6 @@ static unsigned int pack_open_fds;
|
||||
static unsigned int pack_max_fds;
|
||||
static size_t peak_pack_mapped;
|
||||
static size_t pack_mapped;
|
||||
struct packed_git *packed_git;
|
||||
LIST_HEAD(packed_git_mru);
|
||||
|
||||
#define SZ_FMT PRIuMAX
|
||||
static inline uintmax_t sz_fmt(size_t s) { return s; }
|
||||
@ -245,7 +245,7 @@ static int unuse_one_window(struct packed_git *current)
|
||||
|
||||
if (current)
|
||||
scan_windows(current, &lru_p, &lru_w, &lru_l);
|
||||
for (p = packed_git; p; p = p->next)
|
||||
for (p = the_repository->objects->packed_git; p; p = p->next)
|
||||
scan_windows(p, &lru_p, &lru_w, &lru_l);
|
||||
if (lru_p) {
|
||||
munmap(lru_w->base, lru_w->len);
|
||||
@ -311,11 +311,11 @@ static void close_pack(struct packed_git *p)
|
||||
close_pack_index(p);
|
||||
}
|
||||
|
||||
void close_all_packs(void)
|
||||
void close_all_packs(struct raw_object_store *o)
|
||||
{
|
||||
struct packed_git *p;
|
||||
|
||||
for (p = packed_git; p; p = p->next)
|
||||
for (p = o->packed_git; p; p = p->next)
|
||||
if (p->do_not_close)
|
||||
die("BUG: want to close pack marked 'do-not-close'");
|
||||
else
|
||||
@ -383,7 +383,7 @@ static int close_one_pack(void)
|
||||
struct pack_window *mru_w = NULL;
|
||||
int accept_windows_inuse = 1;
|
||||
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = the_repository->objects->packed_git; p; p = p->next) {
|
||||
if (p->pack_fd == -1)
|
||||
continue;
|
||||
find_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse);
|
||||
@ -685,8 +685,8 @@ void install_packed_git(struct packed_git *pack)
|
||||
if (pack->pack_fd != -1)
|
||||
pack_open_fds++;
|
||||
|
||||
pack->next = packed_git;
|
||||
packed_git = pack;
|
||||
pack->next = the_repository->objects->packed_git;
|
||||
the_repository->objects->packed_git = pack;
|
||||
}
|
||||
|
||||
void (*report_garbage)(unsigned seen_bits, const char *path);
|
||||
@ -768,7 +768,8 @@ static void prepare_packed_git_one(char *objdir, int local)
|
||||
base_len = path.len;
|
||||
if (strip_suffix_mem(path.buf, &base_len, ".idx")) {
|
||||
/* Don't reopen a pack we already have. */
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = the_repository->objects->packed_git; p;
|
||||
p = p->next) {
|
||||
size_t len;
|
||||
if (strip_suffix(p->pack_name, ".pack", &len) &&
|
||||
len == base_len &&
|
||||
@ -802,8 +803,6 @@ static void prepare_packed_git_one(char *objdir, int local)
|
||||
strbuf_release(&path);
|
||||
}
|
||||
|
||||
static int approximate_object_count_valid;
|
||||
|
||||
/*
|
||||
* Give a fast, rough count of the number of objects in the repository. This
|
||||
* ignores loose objects completely. If you have a lot of them, then either
|
||||
@ -813,19 +812,20 @@ static int approximate_object_count_valid;
|
||||
*/
|
||||
unsigned long approximate_object_count(void)
|
||||
{
|
||||
static unsigned long count;
|
||||
if (!approximate_object_count_valid) {
|
||||
if (!the_repository->objects->approximate_object_count_valid) {
|
||||
unsigned long count;
|
||||
struct packed_git *p;
|
||||
|
||||
prepare_packed_git();
|
||||
count = 0;
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = the_repository->objects->packed_git; p; p = p->next) {
|
||||
if (open_pack_index(p))
|
||||
continue;
|
||||
count += p->num_objects;
|
||||
}
|
||||
the_repository->objects->approximate_object_count = count;
|
||||
}
|
||||
return count;
|
||||
return the_repository->objects->approximate_object_count;
|
||||
}
|
||||
|
||||
static void *get_next_packed_git(const void *p)
|
||||
@ -868,43 +868,53 @@ static int sort_pack(const void *a_, const void *b_)
|
||||
|
||||
static void rearrange_packed_git(void)
|
||||
{
|
||||
packed_git = llist_mergesort(packed_git, get_next_packed_git,
|
||||
set_next_packed_git, sort_pack);
|
||||
the_repository->objects->packed_git = llist_mergesort(
|
||||
the_repository->objects->packed_git, get_next_packed_git,
|
||||
set_next_packed_git, sort_pack);
|
||||
}
|
||||
|
||||
static void prepare_packed_git_mru(void)
|
||||
{
|
||||
struct packed_git *p;
|
||||
|
||||
INIT_LIST_HEAD(&packed_git_mru);
|
||||
INIT_LIST_HEAD(&the_repository->objects->packed_git_mru);
|
||||
|
||||
for (p = packed_git; p; p = p->next)
|
||||
list_add_tail(&p->mru, &packed_git_mru);
|
||||
for (p = the_repository->objects->packed_git; p; p = p->next)
|
||||
list_add_tail(&p->mru, &the_repository->objects->packed_git_mru);
|
||||
}
|
||||
|
||||
static int prepare_packed_git_run_once = 0;
|
||||
void prepare_packed_git(void)
|
||||
{
|
||||
struct alternate_object_database *alt;
|
||||
|
||||
if (prepare_packed_git_run_once)
|
||||
if (the_repository->objects->packed_git_initialized)
|
||||
return;
|
||||
prepare_packed_git_one(get_object_directory(), 1);
|
||||
prepare_alt_odb();
|
||||
for (alt = alt_odb_list; alt; alt = alt->next)
|
||||
prepare_alt_odb(the_repository);
|
||||
for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next)
|
||||
prepare_packed_git_one(alt->path, 0);
|
||||
rearrange_packed_git();
|
||||
prepare_packed_git_mru();
|
||||
prepare_packed_git_run_once = 1;
|
||||
the_repository->objects->packed_git_initialized = 1;
|
||||
}
|
||||
|
||||
void reprepare_packed_git(void)
|
||||
{
|
||||
approximate_object_count_valid = 0;
|
||||
prepare_packed_git_run_once = 0;
|
||||
the_repository->objects->approximate_object_count_valid = 0;
|
||||
the_repository->objects->packed_git_initialized = 0;
|
||||
prepare_packed_git();
|
||||
}
|
||||
|
||||
struct packed_git *get_packed_git(struct repository *r)
|
||||
{
|
||||
return r->objects->packed_git;
|
||||
}
|
||||
|
||||
struct list_head *get_packed_git_mru(struct repository *r)
|
||||
{
|
||||
return &r->objects->packed_git_mru;
|
||||
}
|
||||
|
||||
unsigned long unpack_object_header_buffer(const unsigned char *buf,
|
||||
unsigned long len, enum object_type *type, unsigned long *sizep)
|
||||
{
|
||||
@ -1013,7 +1023,7 @@ const struct packed_git *has_packed_and_bad(const unsigned char *sha1)
|
||||
struct packed_git *p;
|
||||
unsigned i;
|
||||
|
||||
for (p = packed_git; p; p = p->next)
|
||||
for (p = the_repository->objects->packed_git; p; p = p->next)
|
||||
for (i = 0; i < p->num_bad_objects; i++)
|
||||
if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
|
||||
return p;
|
||||
@ -1833,13 +1843,14 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
|
||||
struct list_head *pos;
|
||||
|
||||
prepare_packed_git();
|
||||
if (!packed_git)
|
||||
if (!the_repository->objects->packed_git)
|
||||
return 0;
|
||||
|
||||
list_for_each(pos, &packed_git_mru) {
|
||||
list_for_each(pos, &the_repository->objects->packed_git_mru) {
|
||||
struct packed_git *p = list_entry(pos, struct packed_git, mru);
|
||||
if (fill_pack_entry(sha1, e, p)) {
|
||||
list_move(&p->mru, &packed_git_mru);
|
||||
list_move(&p->mru,
|
||||
&the_repository->objects->packed_git_mru);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -1886,7 +1897,7 @@ int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags)
|
||||
int pack_errors = 0;
|
||||
|
||||
prepare_packed_git();
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = the_repository->objects->packed_git; p; p = p->next) {
|
||||
if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
|
||||
continue;
|
||||
if ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) &&
|
||||
@ -1917,7 +1928,7 @@ static int add_promisor_object(const struct object_id *oid,
|
||||
|
||||
/*
|
||||
* If this is a tree, commit, or tag, the objects it refers
|
||||
* to are also promisor objects. (Blobs refer to no objects.)
|
||||
* to are also promisor objects. (Blobs refer to no objects->)
|
||||
*/
|
||||
if (obj->type == OBJ_TREE) {
|
||||
struct tree *tree = (struct tree *)obj;
|
||||
|
||||
Reference in New Issue
Block a user