summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2015-04-20 15:55:00 -0400
committerJunio C Hamano <gitster@pobox.com>2015-04-20 13:09:40 -0700
commitee1c6c34ac64c1e10b17a50710ea7002b7e7241f (patch)
tree664c9f30518680d10a7dbdaf72a0eec754bcf714
parentb5f52f372e85c6e461b6123cd7eebd544b439020 (diff)
downloadgit-ee1c6c34ac64c1e10b17a50710ea7002b7e7241f.tar.gz
sha1_file: only freshen packs once per run
Since 33d4221 (write_sha1_file: freshen existing objects, 2014-10-15), we update the mtime of existing objects that we would have written out (had they not existed). For the common case in which many objects are packed, we may update the mtime on a single packfile repeatedly. This can result in a noticeable performance problem if calling utime() is expensive (e.g., because your storage is on NFS). We can fix this by keeping a per-pack flag that lets us freshen only once per program invocation. An alternative would be to keep the packed_git.mtime flag up to date as we freshen, and freshen only once every N seconds. In practice, it's not worth the complexity. We are racing against prune expiration times here, which inherently must be set to accomodate reasonable program running times (because they really care about the time between an object being written and it becoming referenced, and the latter is typically the last step a program takes). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--cache.h1
-rw-r--r--sha1_file.c9
2 files changed, 9 insertions, 1 deletions
diff --git a/cache.h b/cache.h
index c7565f6acb..e917833391 100644
--- a/cache.h
+++ b/cache.h
@@ -1168,6 +1168,7 @@ extern struct packed_git {
int pack_fd;
unsigned pack_local:1,
pack_keep:1,
+ freshened:1,
do_not_close:1;
unsigned char sha1[20];
/* something like ".git/objects/pack/xxxxx.pack" */
diff --git a/sha1_file.c b/sha1_file.c
index cd6c102ccf..bf1bdbcdf5 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2999,7 +2999,14 @@ static int freshen_loose_object(const unsigned char *sha1)
static int freshen_packed_object(const unsigned char *sha1)
{
struct pack_entry e;
- return find_pack_entry(sha1, &e) && freshen_file(e.p->pack_name);
+ if (!find_pack_entry(sha1, &e))
+ return 0;
+ if (e.p->freshened)
+ return 1;
+ if (!freshen_file(e.p->pack_name))
+ return 0;
+ e.p->freshened = 1;
+ return 1;
}
int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *returnsha1)