git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jeff Smith <whydoubt@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, peff@peff.net, Jeff Smith <whydoubt@gmail.com>
Subject: [RFC PATCH 05/10] Split blame origin into its own file
Date: Fri,  5 May 2017 00:27:24 -0500	[thread overview]
Message-ID: <20170505052729.7576-6-whydoubt@gmail.com> (raw)
In-Reply-To: <20170505052729.7576-1-whydoubt@gmail.com>

Signed-off-by: Jeff Smith <whydoubt@gmail.com>
---
 Makefile        |   1 +
 builtin/blame.c | 151 +-------------------------------------------------------
 origin.c        |  62 +++++++++++++++++++++++
 origin.h        | 101 +++++++++++++++++++++++++++++++++++++
 4 files changed, 165 insertions(+), 150 deletions(-)
 create mode 100644 origin.c
 create mode 100644 origin.h

diff --git a/Makefile b/Makefile
index e35542e..8cbb56c 100644
--- a/Makefile
+++ b/Makefile
@@ -791,6 +791,7 @@ LIB_OBJS += notes-merge.o
 LIB_OBJS += notes-utils.o
 LIB_OBJS += object.o
 LIB_OBJS += oidset.o
+LIB_OBJS += origin.o
 LIB_OBJS += pack-bitmap.o
 LIB_OBJS += pack-bitmap-write.o
 LIB_OBJS += pack-check.o
diff --git a/builtin/blame.c b/builtin/blame.c
index cc46f56..7ee84c1 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -28,6 +28,7 @@
 #include "line-log.h"
 #include "dir.h"
 #include "progress.h"
+#include "origin.h"
 
 static char blame_usage[] = N_("git blame [<options>] [<rev-opts>] [<rev>] [--] <file>");
 
@@ -84,50 +85,6 @@ static unsigned blame_copy_score;
 #define METAINFO_SHOWN		(1u<<12)
 #define MORE_THAN_ONE_PATH	(1u<<13)
 
-/*
- * One blob in a commit that is being suspected
- */
-struct origin {
-	int refcnt;
-	/* Record preceding blame record for this blob */
-	struct origin *previous;
-	/* origins are put in a list linked via `next' hanging off the
-	 * corresponding commit's util field in order to make finding
-	 * them fast.  The presence in this chain does not count
-	 * towards the origin's reference count.  It is tempting to
-	 * let it count as long as the commit is pending examination,
-	 * but even under circumstances where the commit will be
-	 * present multiple times in the priority queue of unexamined
-	 * commits, processing the first instance will not leave any
-	 * work requiring the origin data for the second instance.  An
-	 * interspersed commit changing that would have to be
-	 * preexisting with a different ancestry and with the same
-	 * commit date in order to wedge itself between two instances
-	 * of the same commit in the priority queue _and_ produce
-	 * blame entries relevant for it.  While we don't want to let
-	 * us get tripped up by this case, it certainly does not seem
-	 * worth optimizing for.
-	 */
-	struct origin *next;
-	struct commit *commit;
-	/* `suspects' contains blame entries that may be attributed to
-	 * this origin's commit or to parent commits.  When a commit
-	 * is being processed, all suspects will be moved, either by
-	 * assigning them to an origin in a different commit, or by
-	 * shipping them to the scoreboard's ent list because they
-	 * cannot be attributed to a different commit.
-	 */
-	struct blame_entry *suspects;
-	mmfile_t file;
-	struct object_id blob_oid;
-	unsigned mode;
-	/* guilty gets set when shipping any suspects to the final
-	 * blame list instead of other commits
-	 */
-	char guilty;
-	char path[FLEX_ARRAY];
-};
-
 struct progress_info {
 	struct progress *progress;
 	int blamed_lines;
@@ -176,39 +133,6 @@ static void fill_origin_blob(struct diff_options *opt,
 		*file = o->file;
 }
 
-/*
- * Origin is refcounted and usually we keep the blob contents to be
- * reused.
- */
-static inline struct origin *origin_incref(struct origin *o)
-{
-	if (o)
-		o->refcnt++;
-	return o;
-}
-
-static void origin_decref(struct origin *o)
-{
-	if (o && --o->refcnt <= 0) {
-		struct origin *p, *l = NULL;
-		if (o->previous)
-			origin_decref(o->previous);
-		free(o->file.ptr);
-		/* Should be present exactly once in commit chain */
-		for (p = o->commit->util; p; l = p, p = p->next) {
-			if (p == o) {
-				if (l)
-					l->next = p->next;
-				else
-					o->commit->util = p->next;
-				free(o);
-				return;
-			}
-		}
-		die("internal error in blame::origin_decref");
-	}
-}
-
 static void drop_origin_blob(struct origin *o)
 {
 	if (o->file.ptr) {
@@ -218,40 +142,6 @@ static void drop_origin_blob(struct origin *o)
 }
 
 /*
- * Each group of lines is described by a blame_entry; it can be split
- * as we pass blame to the parents.  They are arranged in linked lists
- * kept as `suspects' of some unprocessed origin, or entered (when the
- * blame origin has been finalized) into the scoreboard structure.
- * While the scoreboard structure is only sorted at the end of
- * processing (according to final image line number), the lists
- * attached to an origin are sorted by the target line number.
- */
-struct blame_entry {
-	struct blame_entry *next;
-
-	/* the first line of this group in the final image;
-	 * internally all line numbers are 0 based.
-	 */
-	int lno;
-
-	/* how many lines this group has */
-	int num_lines;
-
-	/* the commit that introduced this group into the final image */
-	struct origin *suspect;
-
-	/* the line number of the first line of this group in the
-	 * suspect's file; internally all line numbers are 0 based.
-	 */
-	int s_lno;
-
-	/* how significant this entry is -- cached to avoid
-	 * scanning the lines over and over.
-	 */
-	unsigned score;
-};
-
-/*
  * Any merge of blames happens on lists of blames that arrived via
  * different parents in a single suspect.  In this case, we want to
  * sort according to the suspect line numbers as opposed to the final
@@ -429,45 +319,6 @@ static void queue_blames(struct scoreboard *sb, struct origin *porigin,
 }
 
 /*
- * Given a commit and a path in it, create a new origin structure.
- * The callers that add blame to the scoreboard should use
- * get_origin() to obtain shared, refcounted copy instead of calling
- * this function directly.
- */
-static struct origin *make_origin(struct commit *commit, const char *path)
-{
-	struct origin *o;
-	FLEX_ALLOC_STR(o, path, path);
-	o->commit = commit;
-	o->refcnt = 1;
-	o->next = commit->util;
-	commit->util = o;
-	return o;
-}
-
-/*
- * Locate an existing origin or create a new one.
- * This moves the origin to front position in the commit util list.
- */
-static struct origin *get_origin(struct commit *commit, const char *path)
-{
-	struct origin *o, *l;
-
-	for (o = commit->util, l = NULL; o; l = o, o = o->next) {
-		if (!strcmp(o->path, path)) {
-			/* bump to front */
-			if (l) {
-				l->next = o->next;
-				o->next = commit->util;
-				commit->util = o;
-			}
-			return origin_incref(o);
-		}
-	}
-	return make_origin(commit, path);
-}
-
-/*
  * Fill the blob_sha1 field of an origin if it hasn't, so that later
  * call to fill_origin_blob() can use it to locate the data.  blob_sha1
  * for an origin is also used to pass the blame for the entire file to
diff --git a/origin.c b/origin.c
new file mode 100644
index 0000000..2ec25c7
--- /dev/null
+++ b/origin.c
@@ -0,0 +1,62 @@
+#include "origin.h"
+
+void origin_decref(struct origin *o)
+{
+	if (o && --o->refcnt <= 0) {
+		struct origin *p, *l = NULL;
+		if (o->previous)
+			origin_decref(o->previous);
+		free(o->file.ptr);
+		/* Should be present exactly once in commit chain */
+		for (p = o->commit->util; p; l = p, p = p->next) {
+			if (p == o) {
+				if (l)
+					l->next = p->next;
+				else
+					o->commit->util = p->next;
+				free(o);
+				return;
+			}
+		}
+		die("internal error in blame::origin_decref");
+	}
+}
+
+/*
+ * Given a commit and a path in it, create a new origin structure.
+ * The callers that add blame to the scoreboard should use
+ * get_origin() to obtain shared, refcounted copy instead of calling
+ * this function directly.
+ */
+struct origin *make_origin(struct commit *commit, const char *path)
+{
+	struct origin *o;
+	FLEX_ALLOC_STR(o, path, path);
+	o->commit = commit;
+	o->refcnt = 1;
+	o->next = commit->util;
+	commit->util = o;
+	return o;
+}
+
+/*
+ * Locate an existing origin or create a new one.
+ * This moves the origin to front position in the commit util list.
+ */
+struct origin *get_origin(struct commit *commit, const char *path)
+{
+	struct origin *o, *l;
+
+	for (o = commit->util, l = NULL; o; l = o, o = o->next) {
+		if (!strcmp(o->path, path)) {
+			/* bump to front */
+			if (l) {
+				l->next = o->next;
+				o->next = commit->util;
+				commit->util = o;
+			}
+			return origin_incref(o);
+		}
+	}
+	return make_origin(commit, path);
+}
diff --git a/origin.h b/origin.h
new file mode 100644
index 0000000..a189b78
--- /dev/null
+++ b/origin.h
@@ -0,0 +1,101 @@
+#ifndef ORIGIN_H
+#define ORIGIN_H
+
+#include "cache.h"
+#include "commit.h"
+#include "xdiff-interface.h"
+
+/*
+ * One blob in a commit that is being suspected
+ */
+struct origin {
+	int refcnt;
+	/* Record preceding blame record for this blob */
+	struct origin *previous;
+	/* origins are put in a list linked via `next' hanging off the
+	 * corresponding commit's util field in order to make finding
+	 * them fast.  The presence in this chain does not count
+	 * towards the origin's reference count.  It is tempting to
+	 * let it count as long as the commit is pending examination,
+	 * but even under circumstances where the commit will be
+	 * present multiple times in the priority queue of unexamined
+	 * commits, processing the first instance will not leave any
+	 * work requiring the origin data for the second instance.  An
+	 * interspersed commit changing that would have to be
+	 * preexisting with a different ancestry and with the same
+	 * commit date in order to wedge itself between two instances
+	 * of the same commit in the priority queue _and_ produce
+	 * blame entries relevant for it.  While we don't want to let
+	 * us get tripped up by this case, it certainly does not seem
+	 * worth optimizing for.
+	 */
+	struct origin *next;
+	struct commit *commit;
+	/* `suspects' contains blame entries that may be attributed to
+	 * this origin's commit or to parent commits.  When a commit
+	 * is being processed, all suspects will be moved, either by
+	 * assigning them to an origin in a different commit, or by
+	 * shipping them to the scoreboard's ent list because they
+	 * cannot be attributed to a different commit.
+	 */
+	struct blame_entry *suspects;
+	mmfile_t file;
+	struct object_id blob_oid;
+	unsigned mode;
+	/* guilty gets set when shipping any suspects to the final
+	 * blame list instead of other commits
+	 */
+	char guilty;
+	char path[FLEX_ARRAY];
+};
+
+/*
+ * Each group of lines is described by a blame_entry; it can be split
+ * as we pass blame to the parents.  They are arranged in linked lists
+ * kept as `suspects' of some unprocessed origin, or entered (when the
+ * blame origin has been finalized) into the scoreboard structure.
+ * While the scoreboard structure is only sorted at the end of
+ * processing (according to final image line number), the lists
+ * attached to an origin are sorted by the target line number.
+ */
+struct blame_entry {
+	struct blame_entry *next;
+
+	/* the first line of this group in the final image;
+	 * internally all line numbers are 0 based.
+	 */
+	int lno;
+
+	/* how many lines this group has */
+	int num_lines;
+
+	/* the commit that introduced this group into the final image */
+	struct origin *suspect;
+
+	/* the line number of the first line of this group in the
+	 * suspect's file; internally all line numbers are 0 based.
+	 */
+	int s_lno;
+
+	/* how significant this entry is -- cached to avoid
+	 * scanning the lines over and over.
+	 */
+	unsigned score;
+};
+
+/*
+ * Origin is refcounted and usually we keep the blob contents to be
+ * reused.
+ */
+static inline struct origin *origin_incref(struct origin *o)
+{
+	if (o)
+		o->refcnt++;
+	return o;
+}
+void origin_decref(struct origin *o);
+
+struct origin *make_origin(struct commit *commit, const char *path);
+struct origin *get_origin(struct commit *commit, const char *path);
+
+#endif /* ORIGIN_H */
-- 
2.9.3


  parent reply	other threads:[~2017-05-05  5:27 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-05  5:27 [RFC PATCH 00/10] Add blame to libgit Jeff Smith
2017-05-05  5:27 ` [RFC PATCH 01/10] Remove unneeded dependency on blob.h from blame Jeff Smith
2017-05-05  7:07   ` Ævar Arnfjörð Bjarmason
     [not found]     ` <CAPX7N=6tQi+WidagvV1BA-CoaiNJj7OO4U7GYXNE-QzyvD=QRQ@mail.gmail.com>
2017-05-05 14:03       ` Jeffrey Smith
2017-05-05  5:27 ` [RFC PATCH 02/10] Move textconv_object to be with other textconv methods Jeff Smith
2017-05-05 17:44   ` Junio C Hamano
2017-05-05 17:50     ` Stefan Beller
2017-05-08  1:02       ` Junio C Hamano
2017-05-08 21:55         ` Jeff King
2017-05-08 22:06           ` Stefan Beller
2017-05-09  1:49           ` Junio C Hamano
2017-05-09  2:34             ` Jeff King
2017-05-05  5:27 ` [RFC PATCH 03/10] Add some missing definitions to header files Jeff Smith
2017-05-05 17:42   ` Junio C Hamano
2017-05-05  5:27 ` [RFC PATCH 04/10] Remove unused parameter from get_origin() Jeff Smith
2017-05-05  5:27 ` Jeff Smith [this message]
2017-05-05  5:27 ` [RFC PATCH 06/10] Move fake_working_tree_commit() to lib Jeff Smith
2017-05-05  5:27 ` [RFC PATCH 07/10] Break out scoreboard a little better Jeff Smith
2017-05-05 17:52   ` Junio C Hamano
2017-05-05  5:27 ` [RFC PATCH 08/10] Split blame scoreboard into its own file Jeff Smith
2017-05-05  5:27 ` [RFC PATCH 09/10] Break out scoreboard init and setup Jeff Smith
2017-05-05  5:27 ` [RFC PATCH 10/10] Move scoreboard init and setup to lib Jeff Smith
2017-05-05 17:54 ` [RFC PATCH 00/10] Add blame to libgit Junio C Hamano
2017-05-14  3:14 ` [RFC PATCH v2 00/22] " Jeff Smith
2017-05-14  3:14   ` [RFC PATCH v2 01/22] blame: remove unneeded dependency on blob.h Jeff Smith
2017-05-14  3:14   ` [RFC PATCH v2 02/22] blame: move textconv_object with related functions Jeff Smith
2017-05-14  3:14   ` [RFC PATCH v2 03/22] blame: remove unused parameters Jeff Smith
2017-05-14  3:14   ` [RFC PATCH v2 04/22] blame: move origin and entry structures to header Jeff Smith
2017-05-14  8:10     ` Junio C Hamano
2017-05-14  3:14   ` [RFC PATCH v2 05/22] blame: move scoreboard structure " Jeff Smith
2017-05-14  3:14   ` [RFC PATCH v2 06/22] blame: move stat counters to scoreboard Jeff Smith
2017-05-14  3:14   ` [RFC PATCH v2 07/22] blame: move copy/move thresholds " Jeff Smith
2017-05-14  3:14   ` [RFC PATCH v2 08/22] blame: move contents_from " Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 09/22] blame: move reverse flag " Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 10/22] blame: move show_root " Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 11/22] blame: move xdl_opts flags " Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 12/22] blame: move no_whole_file_rename flag " Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 13/22] blame: make sanity_check use a callback in scoreboard Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 14/22] blame: move progess updates to a scoreboard callback Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 15/22] blame: wrap blame_sort and compare_blame_final Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 16/22] blame: rework methods that determine 'final' commit Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 17/22] blame: move origin-related methods to libgit Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 18/22] blame: move fake-commit-related " Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 19/22] blame: move scoreboard-related " Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 20/22] blame: create scoreboard init function in libgit Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 21/22] blame: create scoreboard setup " Jeff Smith
2017-05-14  3:15   ` [RFC PATCH v2 22/22] blame: create entry prepend " Jeff Smith
2017-05-15  9:24   ` [RFC PATCH v2 00/22] Add blame to libgit Junio C Hamano
2017-05-15 13:52     ` Jeffrey Smith
2017-05-16  0:23       ` Junio C Hamano
2017-05-16  2:44         ` Jeffrey Smith
2017-05-16  3:21           ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170505052729.7576-6-whydoubt@gmail.com \
    --to=whydoubt@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).