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:
Junio C Hamano
2018-04-11 13:09:55 +09:00
39 changed files with 394 additions and 234 deletions

View File

@ -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;