From: Jeff King <peff@peff.net>
To: Christian Couder <christian.couder@gmail.com>
Cc: Junio C Hamano <gitster@pobox.com>,
Christian Couder <chriscool@tuxfamily.org>,
git <git@vger.kernel.org>, Jakub Narebski <jnareb@gmail.com>,
Eric Sunshine <sunshine@sunshineco.com>
Subject: Re: [PATCH v3 1/4] replace: add --graft option
Date: Sun, 8 Jun 2014 08:04:39 -0400 [thread overview]
Message-ID: <20140608120439.GA21827@sigill.intra.peff.net> (raw)
In-Reply-To: <20140608112333.GA9691@sigill.intra.peff.net>
On Sun, Jun 08, 2014 at 07:23:33AM -0400, Jeff King wrote:
> 4. Keep a static commit_slab that points to the length for each parsed
> commit. We pay the same memory cost as (2), but as it's not part of
> the struct, the cache effects are minimized.
I think I favor this solution, which would look something like this:
-- >8 --
Subject: [PATCH] commit: add slab for commit buffer size
We store the commit object buffer for later reuse as
commit->buffer. However, since we store only a pointer, we
must treat the result as a NUL-terminated string. This is
generally OK for pretty-printing, but could be a problem for
other uses.
Adding a "len" member to "struct commit" would solve this,
but at the cost of bloating the struct even for callers who
do not care about the size or buffer (e.g., traversals like
rev-list or merge-base). Instead, let's use a commit_slab so
that the memory is used only when save_commit_buffer is in
effect (and even then, it should have less cache impact on
most uses of "struct commit").
Signed-off-by: Jeff King <peff@peff.net>
---
I think it would make sense to actually take this one step further,
though, and move commit->buffer into the slab, as well. That has two
advantages:
1. It further decreases the size of "struct commit" for callers who do
not use save_commit_buffer.
2. It ensures that no new callers crop up who set "commit->buffer" but
to not save the size in the slab (you can see in the patch below
that I had to modify builtin/blame.c, which (ab)uses
commit->buffer).
It would be more disruptive to existing callers, but I think the end
result would be pretty clean. The API would be something like:
/* attach buffer to commit */
set_commit_buffer(struct commit *, void *buf, unsigned long size);
/* get buffer, either from slab cache or by calling read_sha1_file */
void *get_commit_buffer(struct commit *, unsigned long *size);
/* free() an allocated buffer from above, noop for cached buffer */
void unused_commit_buffer(struct commit *, void *buf);
/* drop saved commit buffer to free memory */
void free_commit_buffer(struct commit *);
The "get" function would serve the existing callers in pretty.c, as well
as the one I'm adding elsewhere in show_signature. And it should work as
a drop-in read_sha1_file/free replacement for you here.
builtin/blame.c | 2 +-
commit.c | 13 ++++++++++++-
commit.h | 1 +
object.c | 2 +-
4 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/builtin/blame.c b/builtin/blame.c
index a52a279..1945ea4 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -2313,7 +2313,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
ident, ident, path,
(!contents_from ? path :
(!strcmp(contents_from, "-") ? "standard input" : contents_from)));
- commit->buffer = strbuf_detach(&msg, NULL);
+ set_commit_buffer(commit, strbuf_detach(&msg, NULL), msg.len);
if (!contents_from || strcmp("-", contents_from)) {
struct stat st;
diff --git a/commit.c b/commit.c
index f479331..71143ed 100644
--- a/commit.c
+++ b/commit.c
@@ -302,6 +302,17 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s
return 0;
}
+define_commit_slab(commit_size_slab, unsigned long);
+static struct commit_size_slab commit_size;
+
+void set_commit_buffer(struct commit *item, void *buffer, unsigned long size)
+{
+ if (!commit_size.stride)
+ init_commit_size_slab(&commit_size);
+ *commit_size_slab_at(&commit_size, item) = size;
+ item->buffer = buffer;
+}
+
int parse_commit(struct commit *item)
{
enum object_type type;
@@ -324,7 +335,7 @@ int parse_commit(struct commit *item)
}
ret = parse_commit_buffer(item, buffer, size);
if (save_commit_buffer && !ret) {
- item->buffer = buffer;
+ set_commit_buffer(item, buffer, size);
return 0;
}
free(buffer);
diff --git a/commit.h b/commit.h
index a9f177b..7704ab2 100644
--- a/commit.h
+++ b/commit.h
@@ -48,6 +48,7 @@ struct commit *lookup_commit_reference_by_name(const char *name);
struct commit *lookup_commit_or_die(const unsigned char *sha1, const char *ref_name);
int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long size);
+void set_commit_buffer(struct commit *item, void *buffer, unsigned long size);
int parse_commit(struct commit *item);
void parse_commit_or_die(struct commit *item);
diff --git a/object.c b/object.c
index 57a0890..c1c6a24 100644
--- a/object.c
+++ b/object.c
@@ -198,7 +198,7 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
if (parse_commit_buffer(commit, buffer, size))
return NULL;
if (!commit->buffer) {
- commit->buffer = buffer;
+ set_commit_buffer(commit, buffer, size);
*eaten_p = 1;
}
obj = &commit->object;
--
2.0.0.729.g520999f
next prev parent reply other threads:[~2014-06-08 12:05 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-04 19:43 [PATCH v3 0/4] Add --graft option to git replace Christian Couder
2014-06-04 19:43 ` [PATCH v3 1/4] replace: add --graft option Christian Couder
2014-06-05 21:49 ` Junio C Hamano
2014-06-06 15:29 ` Christian Couder
2014-06-06 15:44 ` Christian Couder
2014-06-08 6:49 ` Christian Couder
2014-06-08 11:23 ` Jeff King
2014-06-08 12:04 ` Jeff King [this message]
2014-06-08 12:09 ` Jeff King
2014-06-09 16:43 ` Junio C Hamano
[not found] ` <CAPc5daWBycdmKBZXGhhy4_649p_JFfGf7RQbqa08XA1hL9mFTg@mail.gmail.com>
2014-06-29 6:34 ` Christian Couder
2014-06-30 6:37 ` Junio C Hamano
2014-06-30 10:52 ` Christian Couder
2014-06-06 16:59 ` Junio C Hamano
2014-06-04 19:43 ` [PATCH v3 2/4] replace: add test for --graft Christian Couder
2014-06-04 19:43 ` [PATCH v3 3/4] Documentation: replace: add --graft option Christian Couder
2014-06-04 19:43 ` [PATCH v3 4/4] contrib: add convert-grafts-to-replace-refs.sh Christian Couder
2014-06-05 21:55 ` Junio C Hamano
2014-06-06 15:47 ` Christian Couder
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140608120439.GA21827@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=chriscool@tuxfamily.org \
--cc=christian.couder@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jnareb@gmail.com \
--cc=sunshine@sunshineco.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.
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 NNTP newsgroup(s).