Skip to content

Commit

Permalink
Merge branch 'jt/commit-graph-per-object-store'
Browse files Browse the repository at this point in the history
The singleton commit-graph in-core instance is made per in-core
repository instance.

* jt/commit-graph-per-object-store:
  commit-graph: add repo arg to graph readers
  commit-graph: store graph in struct object_store
  commit-graph: add free_commit_graph
  commit-graph: add missing forward declaration
  object-store: add missing include
  commit-graph: refactor preparing commit graph
  • Loading branch information
gitster committed Aug 2, 2018
2 parents cfec613 + dade47c commit 78a72ad
Show file tree
Hide file tree
Showing 16 changed files with 207 additions and 62 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,7 @@ TEST_BUILTINS_OBJS += test-prio-queue.o
TEST_BUILTINS_OBJS += test-read-cache.o
TEST_BUILTINS_OBJS += test-ref-store.o
TEST_BUILTINS_OBJS += test-regex.o
TEST_BUILTINS_OBJS += test-repository.o
TEST_BUILTINS_OBJS += test-revision-walking.o
TEST_BUILTINS_OBJS += test-run-command.o
TEST_BUILTINS_OBJS += test-scrap-cache-tree.o
Expand Down
2 changes: 2 additions & 0 deletions builtin/commit-graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ static int graph_read(int argc, const char **argv)
printf(" large_edges");
printf("\n");

free_commit_graph(graph);

return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion builtin/fsck.c
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)

check_connectivity();

if (core_commit_graph) {
if (!git_config_get_bool("core.commitgraph", &i) && i) {
struct child_process commit_graph_verify = CHILD_PROCESS_INIT;
const char *verify_argv[] = { "commit-graph", "verify", NULL, NULL, NULL };

Expand Down
1 change: 0 additions & 1 deletion cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,6 @@ extern char *git_replace_ref_base;

extern int fsync_object_files;
extern int core_preload_index;
extern int core_commit_graph;
extern int core_apply_sparse_checkout;
extern int precomposed_unicode;
extern int protect_hfs;
Expand Down
108 changes: 61 additions & 47 deletions commit-graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,53 +183,60 @@ struct commit_graph *load_commit_graph_one(const char *graph_file)
exit(1);
}

/* global storage */
static struct commit_graph *commit_graph = NULL;

static void prepare_commit_graph_one(const char *obj_dir)
static void prepare_commit_graph_one(struct repository *r, const char *obj_dir)
{
char *graph_name;

if (commit_graph)
if (r->objects->commit_graph)
return;

graph_name = get_commit_graph_filename(obj_dir);
commit_graph = load_commit_graph_one(graph_name);
r->objects->commit_graph =
load_commit_graph_one(graph_name);

FREE_AND_NULL(graph_name);
}

static int prepare_commit_graph_run_once = 0;
static void prepare_commit_graph(void)
/*
* Return 1 if commit_graph is non-NULL, and 0 otherwise.
*
* On the first invocation, this function attemps to load the commit
* graph if the_repository is configured to have one.
*/
static int prepare_commit_graph(struct repository *r)
{
struct alternate_object_database *alt;
char *obj_dir;
int config_value;

if (prepare_commit_graph_run_once)
return;
prepare_commit_graph_run_once = 1;
if (r->objects->commit_graph_attempted)
return !!r->objects->commit_graph;
r->objects->commit_graph_attempted = 1;

obj_dir = get_object_directory();
prepare_commit_graph_one(obj_dir);
prepare_alt_odb(the_repository);
for (alt = the_repository->objects->alt_odb_list;
!commit_graph && alt;
if (repo_config_get_bool(r, "core.commitgraph", &config_value) ||
!config_value)
/*
* This repository is not configured to use commit graphs, so
* do not load one. (But report commit_graph_attempted anyway
* so that commit graph loading is not attempted again for this
* repository.)
*/
return 0;

obj_dir = r->objects->objectdir;
prepare_commit_graph_one(r, obj_dir);
prepare_alt_odb(r);
for (alt = r->objects->alt_odb_list;
!r->objects->commit_graph && alt;
alt = alt->next)
prepare_commit_graph_one(alt->path);
prepare_commit_graph_one(r, alt->path);
return !!r->objects->commit_graph;
}

static void close_commit_graph(void)
{
if (!commit_graph)
return;

if (commit_graph->graph_fd >= 0) {
munmap((void *)commit_graph->data, commit_graph->data_len);
commit_graph->data = NULL;
close(commit_graph->graph_fd);
}

FREE_AND_NULL(commit_graph);
free_commit_graph(the_repository->objects->commit_graph);
the_repository->objects->commit_graph = NULL;
}

static int bsearch_graph(struct commit_graph *g, struct object_id *oid, uint32_t *pos)
Expand Down Expand Up @@ -324,8 +331,6 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item
{
uint32_t pos;

if (!core_commit_graph)
return 0;
if (item->object.parsed)
return 1;

Expand All @@ -335,25 +340,20 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item
return 0;
}

int parse_commit_in_graph(struct commit *item)
int parse_commit_in_graph(struct repository *r, struct commit *item)
{
if (!core_commit_graph)
if (!prepare_commit_graph(r))
return 0;

prepare_commit_graph();
if (commit_graph)
return parse_commit_in_graph_one(commit_graph, item);
return 0;
return parse_commit_in_graph_one(r->objects->commit_graph, item);
}

void load_commit_graph_info(struct commit *item)
void load_commit_graph_info(struct repository *r, struct commit *item)
{
uint32_t pos;
if (!core_commit_graph)
if (!prepare_commit_graph(r))
return;
prepare_commit_graph();
if (commit_graph && find_commit_in_graph(item, commit_graph, &pos))
fill_commit_graph_info(item, commit_graph, pos);
if (find_commit_in_graph(item, r->objects->commit_graph, &pos))
fill_commit_graph_info(item, r->objects->commit_graph, pos);
}

static struct tree *load_tree_for_commit(struct commit_graph *g, struct commit *c)
Expand All @@ -379,9 +379,9 @@ static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g,
return load_tree_for_commit(g, (struct commit *)c);
}

struct tree *get_commit_tree_in_graph(const struct commit *c)
struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit *c)
{
return get_commit_tree_in_graph_one(commit_graph, c);
return get_commit_tree_in_graph_one(r->objects->commit_graph, c);
}

static void write_graph_chunk_fanout(struct hashfile *f,
Expand Down Expand Up @@ -697,16 +697,18 @@ void write_commit_graph(const char *obj_dir,
oids.alloc = approximate_object_count() / 4;

if (append) {
prepare_commit_graph_one(obj_dir);
if (commit_graph)
oids.alloc += commit_graph->num_commits;
prepare_commit_graph_one(the_repository, obj_dir);
if (the_repository->objects->commit_graph)
oids.alloc += the_repository->objects->commit_graph->num_commits;
}

if (oids.alloc < 1024)
oids.alloc = 1024;
ALLOC_ARRAY(oids.list, oids.alloc);

if (append && commit_graph) {
if (append && the_repository->objects->commit_graph) {
struct commit_graph *commit_graph =
the_repository->objects->commit_graph;
for (i = 0; i < commit_graph->num_commits; i++) {
const unsigned char *hash = commit_graph->chunk_oid_lookup +
commit_graph->hash_len * i;
Expand Down Expand Up @@ -1027,3 +1029,15 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g)

return verify_commit_graph_error;
}

void free_commit_graph(struct commit_graph *g)
{
if (!g)
return;
if (g->graph_fd >= 0) {
munmap((void *)g->data, g->data_len);
g->data = NULL;
close(g->graph_fd);
}
free(g);
}
11 changes: 8 additions & 3 deletions commit-graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "repository.h"
#include "string-list.h"

struct commit;

char *get_commit_graph_filename(const char *obj_dir);

/*
Expand All @@ -17,17 +19,18 @@ char *get_commit_graph_filename(const char *obj_dir);
*
* See parse_commit_buffer() for the fallback after this call.
*/
int parse_commit_in_graph(struct commit *item);
int parse_commit_in_graph(struct repository *r, struct commit *item);

/*
* It is possible that we loaded commit contents from the commit buffer,
* but we also want to ensure the commit-graph content is correctly
* checked and filled. Fill the graph_pos and generation members of
* the given commit.
*/
void load_commit_graph_info(struct commit *item);
void load_commit_graph_info(struct repository *r, struct commit *item);

struct tree *get_commit_tree_in_graph(const struct commit *c);
struct tree *get_commit_tree_in_graph(struct repository *r,
const struct commit *c);

struct commit_graph {
int graph_fd;
Expand Down Expand Up @@ -56,4 +59,6 @@ void write_commit_graph(const char *obj_dir,

int verify_commit_graph(struct repository *r, struct commit_graph *g);

void free_commit_graph(struct commit_graph *);

#endif
6 changes: 3 additions & 3 deletions commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ struct tree *get_commit_tree(const struct commit *commit)
if (commit->graph_pos == COMMIT_NOT_FROM_GRAPH)
BUG("commit has NULL tree, but was not loaded from commit-graph");

return get_commit_tree_in_graph(commit);
return get_commit_tree_in_graph(the_repository, commit);
}

struct object_id *get_commit_tree_oid(const struct commit *commit)
Expand Down Expand Up @@ -438,7 +438,7 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b
item->date = parse_commit_date(bufptr, tail);

if (check_graph)
load_commit_graph_info(item);
load_commit_graph_info(the_repository, item);

return 0;
}
Expand All @@ -454,7 +454,7 @@ int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_com
return -1;
if (item->object.parsed)
return 0;
if (use_commit_graph && parse_commit_in_graph(item))
if (use_commit_graph && parse_commit_in_graph(the_repository, item))
return 0;
buffer = read_object_file(&item->object.oid, &type, &size);
if (!buffer)
Expand Down
5 changes: 0 additions & 5 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -1320,11 +1320,6 @@ static int git_default_core_config(const char *var, const char *value)
return 0;
}

if (!strcmp(var, "core.commitgraph")) {
core_commit_graph = git_config_bool(var, value);
return 0;
}

if (!strcmp(var, "core.sparsecheckout")) {
core_apply_sparse_checkout = git_config_bool(var, value);
return 0;
Expand Down
1 change: 0 additions & 1 deletion environment.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
char *notes_ref_name;
int grafts_replace_parents = 1;
int core_commit_graph;
int core_apply_sparse_checkout;
int merge_log_config = -1;
int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
Expand Down
6 changes: 6 additions & 0 deletions object-store.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#define OBJECT_STORE_H

#include "oidmap.h"
#include "list.h"
#include "sha1-array.h"
#include "strbuf.h"

struct alternate_object_database {
struct alternate_object_database *next;
Expand Down Expand Up @@ -103,6 +106,9 @@ struct raw_object_store {
*/
struct oidmap *replace_map;

struct commit_graph *commit_graph;
unsigned commit_graph_attempted : 1; /* if loading has been attempted */

/*
* private data
*
Expand Down
5 changes: 5 additions & 0 deletions object.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "alloc.h"
#include "object-store.h"
#include "packfile.h"
#include "commit-graph.h"

unsigned int get_max_object_index(void)
{
Expand Down Expand Up @@ -507,6 +508,10 @@ void raw_object_store_clear(struct raw_object_store *o)
oidmap_free(o->replace_map, 1);
FREE_AND_NULL(o->replace_map);

free_commit_graph(o->commit_graph);
o->commit_graph = NULL;
o->commit_graph_attempted = 0;

free_alt_odbs(o);
o->alt_odb_tail = NULL;

Expand Down
2 changes: 1 addition & 1 deletion ref-filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1713,7 +1713,7 @@ static enum contains_result contains_tag_algo(struct commit *candidate,

for (p = want; p; p = p->next) {
struct commit *c = p->item;
load_commit_graph_info(c);
load_commit_graph_info(the_repository, c);
if (c->generation < cutoff)
cutoff = c->generation;
}
Expand Down
Loading

0 comments on commit 78a72ad

Please sign in to comment.