Skip to content

Commit

Permalink
survey: add commit name-rev lookup to each large_item
Browse files Browse the repository at this point in the history
Signed-off-by: Jeff Hostetler <jeffhostetler@github.com>
  • Loading branch information
jeffhostetler committed May 20, 2024
1 parent 0710898 commit dc5dd68
Showing 1 changed file with 85 additions and 4 deletions.
89 changes: 85 additions & 4 deletions builtin/survey.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "ref-filter.h"
#include "refs.h"
#include "revision.h"
#include "run-command.h"
#include "strbuf.h"
#include "strvec.h"
#include "trace2.h"
Expand Down Expand Up @@ -360,6 +361,12 @@ struct large_item {
* order).
*/
struct object_id containing_commit_oid;

/*
* Lookup `containing_commit_oid` using `git name-rev`.
* Lazy allocate this post-treewalk.
*/
struct strbuf *name_rev;
};

struct large_item_vec {
Expand Down Expand Up @@ -401,6 +408,11 @@ static void free_large_item_vec(struct large_item_vec *vec)
for (k = 0; k < vec->nr_items; k++) {
strbuf_release(vec->items[k].name);
free(vec->items[k].name);

if (vec->items[k].name_rev) {
strbuf_release(vec->items[k].name_rev);
free(vec->items[k].name_rev);
}
}

free(vec->dimension_label);
Expand Down Expand Up @@ -437,6 +449,9 @@ static void maybe_insert_large_item(struct large_item_vec *vec,
* The last large_item in the vector is about to be
* overwritten by the previous one during the shift.
* Steal its allocated strbuf and reuse it.
*
* We can ignore .name_rev because it will not be
* allocated until after the treewalk.
*/
pbuf_temp = vec->items[vec->nr_items - 1].name;
strbuf_reset(pbuf_temp);
Expand All @@ -460,6 +475,51 @@ static void maybe_insert_large_item(struct large_item_vec *vec,
}
}

/*
* Try to run `git name-rev` on each of the containing-commit-oid's
* in this large-item-vec to get a pretty name for each OID. Silently
* ignore errors if it fails because this info is nice to have but not
* essential.
*/
static void large_item_vec_lookup_name_rev(struct large_item_vec *vec)
{
struct child_process cp = CHILD_PROCESS_INIT;
struct strbuf in = STRBUF_INIT;
struct strbuf out = STRBUF_INIT;
const char *line;
size_t k;

if (!vec || !vec->nr_items)
return;

for (k = 0; k < vec->nr_items; k++)
strbuf_addf(&in, "%s\n", oid_to_hex(&vec->items[k].containing_commit_oid));

cp.git_cmd = 1;
strvec_pushl(&cp.args, "name-rev", "--name-only", "--annotate-stdin", NULL);
if (pipe_command(&cp, in.buf, in.len, &out, 0, NULL, 0)) {
strbuf_release(&in);
strbuf_release(&out);
return;
}

line = out.buf;
k = 0;
while (*line) {
const char *eol = strchrnul(line, '\n');

vec->items[k].name_rev = xcalloc(1, sizeof(struct strbuf));
strbuf_init(vec->items[k].name_rev, 0);
strbuf_add(vec->items[k].name_rev, line, (eol - line));

line = eol + 1;
k++;
}

strbuf_release(&in);
strbuf_release(&out);
}

/*
* Common fields for any type of object.
*/
Expand Down Expand Up @@ -739,15 +799,16 @@ static void traverse_commit_cb(struct commit *commit, void *data)
k = commit_list_count(commit->parents);

/*
* Pass null_oid() for the containing-commit-oid, since this object
* is the commit.
* Send the commit-oid as both the OID and the CONTAINING-COMMIT-OID.
* This is somewhat redundant, but lets us later do `git name-rev`
* using the containing-oid in a consistent fashion.
*/
maybe_insert_large_item(psc->vec_largest_by_nr_parents, k,
&commit->object.oid, NULL,
null_oid());
&commit->object.oid);
maybe_insert_large_item(psc->vec_largest_by_size_bytes, object_length,
&commit->object.oid, NULL,
null_oid());
&commit->object.oid);

if (k >= PVEC_LEN)
k = PVEC_LEN - 1;
Expand Down Expand Up @@ -928,6 +989,17 @@ static void do_calc_stats_refs(struct ref_array *ref_array)
}
}

static void do_lookup_name_rev(void)
{
large_item_vec_lookup_name_rev(survey_stats.commits.vec_largest_by_nr_parents);
large_item_vec_lookup_name_rev(survey_stats.commits.vec_largest_by_size_bytes);

large_item_vec_lookup_name_rev(survey_stats.trees.vec_largest_by_nr_entries);
large_item_vec_lookup_name_rev(survey_stats.trees.vec_largest_by_size_bytes);

large_item_vec_lookup_name_rev(survey_stats.blobs.vec_largest_by_size_bytes);
}

/*
* The REFS phase:
*
Expand All @@ -954,7 +1026,13 @@ static void survey_phase_refs(void)
do_treewalk_reachable(&ref_array);
trace2_region_leave("survey", "phase/treewalk", the_repository);

trace2_region_enter("survey", "phase/calcstats", the_repository);
do_calc_stats_refs(&ref_array);
trace2_region_leave("survey", "phase/calcstats", the_repository);

trace2_region_enter("survey", "phase/namerev", the_repository);
do_lookup_name_rev();
trace2_region_enter("survey", "phase/namerev", the_repository);

ref_array_clear(&ref_array);
}
Expand Down Expand Up @@ -1094,6 +1172,9 @@ static void write_large_item_vec_json(struct json_writer *jw,
if (!is_null_oid(&pk->containing_commit_oid))
jw_object_string(jw, "commit_oid",
oid_to_hex(&pk->containing_commit_oid));
if (pk->name_rev->len)
jw_object_string(jw, "name_rev",
pk->name_rev->buf);
}
jw_end(jw);
}
Expand Down

0 comments on commit dc5dd68

Please sign in to comment.