ioptimization: read stats once and remember it - stagit-gopher - A git gopher frontend. (mirror) Err bitreich.org 70 hgit clone git://bitreich.org/stagit-gopher/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/stagit-gopher/ URL:git://bitreich.org/stagit-gopher/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/stagit-gopher/ bitreich.org 70 1Log /scm/stagit-gopher/log.gph bitreich.org 70 1Files /scm/stagit-gopher/files.gph bitreich.org 70 1Refs /scm/stagit-gopher/refs.gph bitreich.org 70 1Tags /scm/stagit-gopher/tag bitreich.org 70 1README /scm/stagit-gopher/file/README.gph bitreich.org 70 1LICENSE /scm/stagit-gopher/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit 914880f31b04222fa2815f4f35543b72f881d5e4 /scm/stagit-gopher/commit/914880f31b04222fa2815f4f35543b72f881d5e4.gph bitreich.org 70 1parent 0bc47da0f7b66614cdf499755ceca1dc13ff91cd /scm/stagit-gopher/commit/0bc47da0f7b66614cdf499755ceca1dc13ff91cd.gph bitreich.org 70 hAuthor: Hiltjo Posthuma URL:mailto:hiltjo@codemadness.org bitreich.org 70 iDate: Sat, 30 Apr 2016 11:54:33 +0200 Err bitreich.org 70 i Err bitreich.org 70 ioptimization: read stats once and remember it Err bitreich.org 70 i Err bitreich.org 70 ifor an initial run and new commits this speeds stagit up a bit: Err bitreich.org 70 ion an initial run of sbase goes from about 4 seconds to 2.8 on my machine. Err bitreich.org 70 i Err bitreich.org 70 inow we can't use statsbuf, so create the stats string ourselves, while at it Err bitreich.org 70 icolor the + and - using a style (can be disabled for the color-haters out Err bitreich.org 70 ithere ;)). Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M stagit.c | 186 ++++++++++++++++++++++++------- Err bitreich.org 70 i M style.css | 2 ++ Err bitreich.org 70 i Err bitreich.org 70 i2 files changed, 149 insertions(+), 39 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/stagit.c b/stagit.c /scm/stagit-gopher/file/stagit.c.gph bitreich.org 70 i@@ -15,6 +15,13 @@ Err bitreich.org 70 i #include "compat.h" Err bitreich.org 70 i #include "config.h" Err bitreich.org 70 i Err bitreich.org 70 i+struct deltainfo { Err bitreich.org 70 i+ git_patch *patch; Err bitreich.org 70 i+ Err bitreich.org 70 i+ size_t addcount; Err bitreich.org 70 i+ size_t delcount; Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i struct commitinfo { Err bitreich.org 70 i const git_oid *id; Err bitreich.org 70 i Err bitreich.org 70 i@@ -25,16 +32,18 @@ struct commitinfo { Err bitreich.org 70 i const char *summary; Err bitreich.org 70 i const char *msg; Err bitreich.org 70 i Err bitreich.org 70 i- git_diff_stats *stats; Err bitreich.org 70 i- git_diff *diff; Err bitreich.org 70 i- git_commit *commit; Err bitreich.org 70 i- git_commit *parent; Err bitreich.org 70 i- git_tree *commit_tree; Err bitreich.org 70 i- git_tree *parent_tree; Err bitreich.org 70 i+ git_diff *diff; Err bitreich.org 70 i+ git_commit *commit; Err bitreich.org 70 i+ git_commit *parent; Err bitreich.org 70 i+ git_tree *commit_tree; Err bitreich.org 70 i+ git_tree *parent_tree; Err bitreich.org 70 i Err bitreich.org 70 i size_t addcount; Err bitreich.org 70 i size_t delcount; Err bitreich.org 70 i size_t filecount; Err bitreich.org 70 i+ Err bitreich.org 70 i+ struct deltainfo **deltas; Err bitreich.org 70 i+ size_t ndeltas; Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i static git_repository *repo; Err bitreich.org 70 i@@ -49,12 +58,95 @@ static char cloneurl[1024]; Err bitreich.org 70 i static int haslicense, hasreadme, hassubmodules; Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i+deltainfo_free(struct deltainfo *di) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ if (!di) Err bitreich.org 70 i+ return; Err bitreich.org 70 i+ git_patch_free(di->patch); Err bitreich.org 70 i+ di->patch = NULL; Err bitreich.org 70 i+ free(di); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+commitinfo_getstats(struct commitinfo *ci) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ struct deltainfo *di; Err bitreich.org 70 i+ const git_diff_delta *delta; Err bitreich.org 70 i+ const git_diff_hunk *hunk; Err bitreich.org 70 i+ const git_diff_line *line; Err bitreich.org 70 i+ git_patch *patch = NULL; Err bitreich.org 70 i+ size_t ndeltas, nhunks, nhunklines; Err bitreich.org 70 i+ size_t i, j, k; Err bitreich.org 70 i+ Err bitreich.org 70 i+ ndeltas = git_diff_num_deltas(ci->diff); Err bitreich.org 70 i+ if (ndeltas && !(ci->deltas = calloc(ndeltas, sizeof(struct deltainfo *)))) Err bitreich.org 70 i+ err(1, "calloc"); Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (i = 0; i < ndeltas; i++) { Err bitreich.org 70 i+ if (!(di = calloc(1, sizeof(struct deltainfo)))) Err bitreich.org 70 i+ err(1, "calloc"); Err bitreich.org 70 i+ if (git_patch_from_diff(&patch, ci->diff, i)) { Err bitreich.org 70 i+ git_patch_free(patch); Err bitreich.org 70 i+ goto err; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ di->patch = patch; Err bitreich.org 70 i+ ci->deltas[i] = di; Err bitreich.org 70 i+ Err bitreich.org 70 i+ delta = git_patch_get_delta(patch); Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* check binary data */ Err bitreich.org 70 i+ if (delta->flags & GIT_DIFF_FLAG_BINARY) Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ Err bitreich.org 70 i+ nhunks = git_patch_num_hunks(patch); Err bitreich.org 70 i+ for (j = 0; j < nhunks; j++) { Err bitreich.org 70 i+ if (git_patch_get_hunk(&hunk, &nhunklines, patch, j)) Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ for (k = 0; ; k++) { Err bitreich.org 70 i+ if (git_patch_get_line_in_hunk(&line, patch, j, k)) Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ if (line->old_lineno == -1) { Err bitreich.org 70 i+ di->addcount++; Err bitreich.org 70 i+ ci->addcount++; Err bitreich.org 70 i+ } else if (line->new_lineno == -1) { Err bitreich.org 70 i+ di->delcount++; Err bitreich.org 70 i+ ci->delcount++; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ ci->ndeltas = i; Err bitreich.org 70 i+ ci->filecount = i; Err bitreich.org 70 i+ Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+err: Err bitreich.org 70 i+ if (ci->deltas) Err bitreich.org 70 i+ for (i = 0; i < ci->ndeltas; i++) Err bitreich.org 70 i+ deltainfo_free(ci->deltas[i]); Err bitreich.org 70 i+ free(ci->deltas); Err bitreich.org 70 i+ ci->deltas = NULL; Err bitreich.org 70 i+ ci->ndeltas = 0; Err bitreich.org 70 i+ ci->addcount = 0; Err bitreich.org 70 i+ ci->delcount = 0; Err bitreich.org 70 i+ ci->filecount = 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void Err bitreich.org 70 i commitinfo_free(struct commitinfo *ci) Err bitreich.org 70 i { Err bitreich.org 70 i+ size_t i; Err bitreich.org 70 i+ Err bitreich.org 70 i if (!ci) Err bitreich.org 70 i return; Err bitreich.org 70 i Err bitreich.org 70 i- git_diff_stats_free(ci->stats); Err bitreich.org 70 i+ if (ci->deltas) Err bitreich.org 70 i+ for (i = 0; i < ci->ndeltas; i++) Err bitreich.org 70 i+ deltainfo_free(ci->deltas[i]); Err bitreich.org 70 i+ free(ci->deltas); Err bitreich.org 70 i+ ci->deltas = NULL; Err bitreich.org 70 i git_diff_free(ci->diff); Err bitreich.org 70 i git_tree_free(ci->commit_tree); Err bitreich.org 70 i git_tree_free(ci->parent_tree); Err bitreich.org 70 i@@ -66,6 +158,7 @@ commitinfo_getbyoid(const git_oid *id) Err bitreich.org 70 i { Err bitreich.org 70 i struct commitinfo *ci; Err bitreich.org 70 i git_diff_options opts; Err bitreich.org 70 i+ const git_oid *oid; Err bitreich.org 70 i int error; Err bitreich.org 70 i Err bitreich.org 70 i if (!(ci = calloc(1, sizeof(struct commitinfo)))) Err bitreich.org 70 i@@ -82,26 +175,24 @@ commitinfo_getbyoid(const git_oid *id) Err bitreich.org 70 i ci->summary = git_commit_summary(ci->commit); Err bitreich.org 70 i ci->msg = git_commit_message(ci->commit); Err bitreich.org 70 i Err bitreich.org 70 i- if ((error = git_commit_tree(&(ci->commit_tree), ci->commit))) Err bitreich.org 70 i+ oid = git_commit_tree_id(ci->commit); Err bitreich.org 70 i+ if ((error = git_tree_lookup(&(ci->commit_tree), repo, oid))) Err bitreich.org 70 i goto err; Err bitreich.org 70 i if (!(error = git_commit_parent(&(ci->parent), ci->commit, 0))) { Err bitreich.org 70 i- if ((error = git_commit_tree(&(ci->parent_tree), ci->parent))) Err bitreich.org 70 i- goto err; Err bitreich.org 70 i- } else { Err bitreich.org 70 i- ci->parent = NULL; Err bitreich.org 70 i- ci->parent_tree = NULL; Err bitreich.org 70 i+ oid = git_commit_tree_id(ci->parent); Err bitreich.org 70 i+ if ((error = git_tree_lookup(&(ci->parent_tree), repo, oid))) { Err bitreich.org 70 i+ ci->parent = NULL; Err bitreich.org 70 i+ ci->parent_tree = NULL; Err bitreich.org 70 i+ } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i git_diff_init_options(&opts, GIT_DIFF_OPTIONS_VERSION); Err bitreich.org 70 i opts.flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH; Err bitreich.org 70 i if ((error = git_diff_tree_to_tree(&(ci->diff), repo, ci->parent_tree, ci->commit_tree, &opts))) Err bitreich.org 70 i goto err; Err bitreich.org 70 i- if (git_diff_get_stats(&(ci->stats), ci->diff)) Err bitreich.org 70 i- goto err; Err bitreich.org 70 i Err bitreich.org 70 i- ci->addcount = git_diff_stats_insertions(ci->stats); Err bitreich.org 70 i- ci->delcount = git_diff_stats_deletions(ci->stats); Err bitreich.org 70 i- ci->filecount = git_diff_stats_files_changed(ci->stats); Err bitreich.org 70 i+ if (commitinfo_getstats(ci) == -1) Err bitreich.org 70 i+ goto err; Err bitreich.org 70 i Err bitreich.org 70 i return ci; Err bitreich.org 70 i Err bitreich.org 70 i@@ -332,33 +423,55 @@ printshowfile(FILE *fp, struct commitinfo *ci) Err bitreich.org 70 i const git_diff_hunk *hunk; Err bitreich.org 70 i const git_diff_line *line; Err bitreich.org 70 i git_patch *patch; Err bitreich.org 70 i- git_buf statsbuf; Err bitreich.org 70 i- size_t ndeltas, nhunks, nhunklines; Err bitreich.org 70 i+ size_t nhunks, nhunklines, changed, add, del, total; Err bitreich.org 70 i size_t i, j, k; Err bitreich.org 70 i+ char linestr[80]; Err bitreich.org 70 i Err bitreich.org 70 i printcommit(fp, ci); Err bitreich.org 70 i Err bitreich.org 70 i- memset(&statsbuf, 0, sizeof(statsbuf)); Err bitreich.org 70 i+ if (!ci->deltas) Err bitreich.org 70 i+ return; Err bitreich.org 70 i Err bitreich.org 70 i /* diff stat */ Err bitreich.org 70 i- if (ci->stats && Err bitreich.org 70 i- !git_diff_stats_to_buf(&statsbuf, ci->stats, Err bitreich.org 70 i- GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_SHORT, 80)) { Err bitreich.org 70 i- if (statsbuf.ptr && statsbuf.ptr[0]) { Err bitreich.org 70 i- fputs("Diffstat:\n", fp); Err bitreich.org 70 i- xmlencode(fp, statsbuf.ptr, strlen(statsbuf.ptr)); Err bitreich.org 70 i+ fputs("Diffstat:\n", fp); Err bitreich.org 70 i+ for (i = 0; i < ci->ndeltas; i++) { Err bitreich.org 70 i+ delta = git_patch_get_delta(ci->deltas[i]->patch); Err bitreich.org 70 i+ fputs("\n", fp); Err bitreich.org 70 i } Err bitreich.org 70 i+ fprintf(fp, "
", fp); Err bitreich.org 70 i+ xmlencode(fp, delta->old_file.path, strlen(delta->old_file.path)); Err bitreich.org 70 i+ if (strcmp(delta->old_file.path, delta->new_file.path)) { Err bitreich.org 70 i+ fputs(" -> ", fp); Err bitreich.org 70 i+ xmlencode(fp, delta->new_file.path, strlen(delta->new_file.path)); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ add = ci->deltas[i]->addcount; Err bitreich.org 70 i+ del = ci->deltas[i]->delcount; Err bitreich.org 70 i+ changed = add + del; Err bitreich.org 70 i+ total = sizeof(linestr) - 2; Err bitreich.org 70 i+ if (changed > total) { Err bitreich.org 70 i+ if (add) Err bitreich.org 70 i+ add = ((float)total / changed * add) + 1; Err bitreich.org 70 i+ if (del) Err bitreich.org 70 i+ del = ((float)total / changed * del) + 1; Err bitreich.org 70 i } Err bitreich.org 70 i+ memset(&linestr, '+', add); Err bitreich.org 70 i+ memset(&linestr[add], '-', del); Err bitreich.org 70 i+ Err bitreich.org 70 i+ fprintf(fp, " | %zu ", Err bitreich.org 70 i+ ci->deltas[i]->addcount + ci->deltas[i]->delcount); Err bitreich.org 70 i+ fwrite(&linestr, 1, add, fp); Err bitreich.org 70 i+ fputs("", fp); Err bitreich.org 70 i+ fwrite(&linestr[add], 1, del, fp); Err bitreich.org 70 i+ fputs("
%zu file%s changed, %zu insertion%s(+), %zu deletion%s(-)\n", Err bitreich.org 70 i+ ci->filecount, ci->filecount == 1 ? "" : "s", Err bitreich.org 70 i+ ci->addcount, ci->addcount == 1 ? "" : "s", Err bitreich.org 70 i+ ci->delcount, ci->delcount == 1 ? "" : "s"); Err bitreich.org 70 i Err bitreich.org 70 i fputs("
", fp); Err bitreich.org 70 i Err bitreich.org 70 i- ndeltas = git_diff_num_deltas(ci->diff); Err bitreich.org 70 i- for (i = 0; i < ndeltas; i++) { Err bitreich.org 70 i- if (git_patch_from_diff(&patch, ci->diff, i)) { Err bitreich.org 70 i- git_patch_free(patch); Err bitreich.org 70 i- break; Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i+ for (i = 0; i < ci->ndeltas; i++) { Err bitreich.org 70 i+ patch = ci->deltas[i]->patch; Err bitreich.org 70 i delta = git_patch_get_delta(patch); Err bitreich.org 70 i fprintf(fp, "diff --git a/%s b/%s\n", Err bitreich.org 70 i relpath, delta->old_file.path, delta->old_file.path, Err bitreich.org 70 i@@ -367,7 +480,6 @@ printshowfile(FILE *fp, struct commitinfo *ci) Err bitreich.org 70 i /* check binary data */ Err bitreich.org 70 i if (delta->flags & GIT_DIFF_FLAG_BINARY) { Err bitreich.org 70 i fputs("Binary files differ\n", fp); Err bitreich.org 70 i- git_patch_free(patch); Err bitreich.org 70 i continue; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -396,11 +508,7 @@ printshowfile(FILE *fp, struct commitinfo *ci) Err bitreich.org 70 i fputs("", fp); Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i- git_patch_free(patch); Err bitreich.org 70 i } Err bitreich.org 70 i- git_buf_free(&statsbuf); Err bitreich.org 70 i- Err bitreich.org 70 i- return; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 1diff --git a/style.css b/style.css /scm/stagit-gopher/file/style.css.gph bitreich.org 70 i@@ -79,10 +79,12 @@ pre a.h { Err bitreich.org 70 i color: #00a; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i+span.i, Err bitreich.org 70 i pre a.i { Err bitreich.org 70 i color: #070; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i+span.d, Err bitreich.org 70 i pre a.d { Err bitreich.org 70 i color: #e00; Err bitreich.org 70 i } Err bitreich.org 70 .