git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Pierre Habouzit <madcoder@debian.org>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org
Subject: [PATCH 3/3] fast-import optimization:
Date: Mon, 17 Sep 2007 14:00:38 +0200	[thread overview]
Message-ID: <20070917125259.2DE83344A4A@madism.org> (raw)
In-Reply-To: <20070917125211.GA18176@artemis.corp>

Now that cmd_data acts on a strbuf, make last_object stashed buffer be a
strbuf as well. On new stash, don't free the last stashed buffer, rather
swap it with the one you will stash, this way, callers of store_object can
act on static strbufs, and at some point, fast-import won't allocate new
memory for objects buffers.
---
 fast-import.c |   52 ++++++++++++++++++++--------------------------------
 1 files changed, 20 insertions(+), 32 deletions(-)

diff --git a/fast-import.c b/fast-import.c
index e456eab..e2a4834 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -182,11 +182,10 @@ struct mark_set
 
 struct last_object
 {
-	void *data;
-	unsigned long len;
+	struct strbuf data;
 	uint32_t offset;
 	unsigned int depth;
-	unsigned no_free:1;
+	unsigned no_swap : 1;
 };
 
 struct mem_pool
@@ -310,7 +309,7 @@ static struct mark_set *marks;
 static const char* mark_file;
 
 /* Our last blob */
-static struct last_object last_blob;
+static struct last_object last_blob = { STRBUF_INIT, 0, 0, 0 };
 
 /* Tree management */
 static unsigned int tree_entry_alloc = 1000;
@@ -950,9 +949,7 @@ static void end_packfile(void)
 	free(old_p);
 
 	/* We can't carry a delta across packfiles. */
-	free(last_blob.data);
-	last_blob.data = NULL;
-	last_blob.len = 0;
+	strbuf_release(&last_blob.data);
 	last_blob.offset = 0;
 	last_blob.depth = 0;
 }
@@ -1024,8 +1021,8 @@ static int store_object(
 		return 1;
 	}
 
-	if (last && last->data && last->depth < max_depth) {
-		delta = diff_delta(last->data, last->len,
+	if (last && last->data.buf && last->depth < max_depth) {
+		delta = diff_delta(last->data.buf, last->data.len,
 			dat->buf, dat->len,
 			&deltalen, 0);
 		if (delta && deltalen >= dat->len) {
@@ -1111,11 +1108,14 @@ static int store_object(
 	free(out);
 	free(delta);
 	if (last) {
-		if (!last->no_free)
-			free(last->data);
+		if (last->no_swap) {
+			last->data = *dat;
+		} else {
+			struct strbuf tmp = *dat;
+			*dat = last->data;
+			last->data = tmp;
+		}
 		last->offset = e->offset;
-		last->data = dat->buf;
-		last->len = dat->len;
 	}
 	return 0;
 }
@@ -1242,7 +1242,7 @@ static void store_tree(struct tree_entry *root)
 {
 	struct tree_content *t = root->tree;
 	unsigned int i, j, del;
-	struct last_object lo;
+	struct last_object lo = { STRBUF_INIT, 0, 0, /* no_swap */ 1 };
 	struct object_entry *le;
 
 	if (!is_null_sha1(root->versions[1].sha1))
@@ -1254,19 +1254,11 @@ static void store_tree(struct tree_entry *root)
 	}
 
 	le = find_object(root->versions[0].sha1);
-	if (!S_ISDIR(root->versions[0].mode)
-		|| !le
-		|| le->pack_id != pack_id) {
-		lo.data = NULL;
-		lo.depth = 0;
-		lo.no_free = 0;
-	} else {
+	if (S_ISDIR(root->versions[0].mode) && le && le->pack_id == pack_id) {
 		mktree(t, 0, &old_tree);
-		lo.len  = old_tree.len;
-		lo.data = old_tree.buf;
+		lo.data = old_tree;
 		lo.offset = le->offset;
 		lo.depth = t->delta_depth;
-		lo.no_free = 1;
 	}
 
 	mktree(t, 1, &new_tree);
@@ -1714,14 +1706,12 @@ static char *parse_ident(const char *buf)
 
 static void cmd_new_blob(void)
 {
-	struct strbuf buf;
+	static struct strbuf buf = STRBUF_INIT;
 
 	read_next_command();
 	cmd_mark();
-	strbuf_init(&buf, 0);
 	cmd_data(&buf);
-	if (store_object(OBJ_BLOB, &buf, &last_blob, NULL, next_mark))
-		strbuf_release(&buf);
+	store_object(OBJ_BLOB, &buf, &last_blob, NULL, next_mark);
 }
 
 static void unload_one_branch(void)
@@ -1817,15 +1807,13 @@ static void file_change_m(struct branch *b)
 	}
 
 	if (inline_data) {
-		struct strbuf buf;
+		static struct strbuf buf = STRBUF_INIT;
 
 		if (!p_uq)
 			p = p_uq = xstrdup(p);
 		read_next_command();
-		strbuf_init(&buf, 0);
 		cmd_data(&buf);
-		if (store_object(OBJ_BLOB, &buf, &last_blob, sha1, 0))
-			strbuf_release(&buf);
+		store_object(OBJ_BLOB, &buf, &last_blob, sha1, 0);
 	} else if (oe) {
 		if (oe->type != OBJ_BLOB)
 			die("Not a blob (actually a %s): %s",
-- 
1.5.3.1

  parent reply	other threads:[~2007-09-17 12:53 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-17 12:52 [PATCH 0/3] the return of the strbuf Pierre Habouzit
2007-09-17  9:19 ` [PATCH 1/3] Drop strbuf's 'eof' marker, and make read_line a first class citizen Pierre Habouzit
2007-09-17 11:48 ` [PATCH 2/3] fast-import was using dbuf's, replace them with strbuf's Pierre Habouzit
2007-09-17 12:00 ` Pierre Habouzit [this message]
2007-09-17 13:35 ` [PATCH 0/3] the return of the strbuf Pierre Habouzit
2007-09-18  3:57   ` Shawn O. Pearce
2007-09-20 11:49     ` Johannes Schindelin
2007-09-20 14:19       ` Shawn O. Pearce
2007-09-20 21:41       ` Junio C Hamano
2007-09-20 21:52         ` Johannes Schindelin
2007-09-18  7:56 ` 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=20070917125259.2DE83344A4A@madism.org \
    --to=madcoder@debian.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /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).