summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4739351)
raw | patch | inline | side by side (parent: 4739351)
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | |
Mon, 7 Nov 2011 02:59:25 +0000 (09:59 +0700) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Mon, 7 Nov 2011 04:31:28 +0000 (20:31 -0800) |
During verify_pack() all objects are read for SHA-1 check. Then
fsck_sha1() is called on every object, which read the object again
(fsck_sha1 -> parse_object -> read_sha1_file).
Avoid reading an object twice, do fsck_sha1 while we have an object
uncompressed data in verify_pack.
On git.git, with this patch I got:
$ /usr/bin/time ./git fsck >/dev/null
98.97user 0.90system 1:40.01elapsed 99%CPU (0avgtext+0avgdata 616624maxresident)k
0inputs+0outputs (0major+194186minor)pagefaults 0swaps
Without it:
$ /usr/bin/time ./git fsck >/dev/null
231.23user 2.35system 3:53.82elapsed 99%CPU (0avgtext+0avgdata 636688maxresident)k
0inputs+0outputs (0major+461629minor)pagefaults 0swaps
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
fsck_sha1() is called on every object, which read the object again
(fsck_sha1 -> parse_object -> read_sha1_file).
Avoid reading an object twice, do fsck_sha1 while we have an object
uncompressed data in verify_pack.
On git.git, with this patch I got:
$ /usr/bin/time ./git fsck >/dev/null
98.97user 0.90system 1:40.01elapsed 99%CPU (0avgtext+0avgdata 616624maxresident)k
0inputs+0outputs (0major+194186minor)pagefaults 0swaps
Without it:
$ /usr/bin/time ./git fsck >/dev/null
231.23user 2.35system 3:53.82elapsed 99%CPU (0avgtext+0avgdata 636688maxresident)k
0inputs+0outputs (0major+461629minor)pagefaults 0swaps
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/fsck.c | patch | blob | history | |
pack-check.c | patch | blob | history | |
pack.h | patch | blob | history |
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 4ead98dcab276b4177fad302ed062a3fb584c9ea..0603f6444e1b5057193b6dba5e6489e6935ca119 100644 (file)
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
}
}
-static int fsck_sha1(const unsigned char *sha1)
+static int fsck_obj(struct object *obj)
{
- struct object *obj = parse_object(sha1);
- if (!obj) {
- errors_found |= ERROR_OBJECT;
- return error("%s: object corrupt or missing",
- sha1_to_hex(sha1));
- }
if (obj->flags & SEEN)
return 0;
obj->flags |= SEEN;
return 0;
}
+static int fsck_sha1(const unsigned char *sha1)
+{
+ struct object *obj = parse_object(sha1);
+ if (!obj) {
+ errors_found |= ERROR_OBJECT;
+ return error("%s: object corrupt or missing",
+ sha1_to_hex(sha1));
+ }
+ return fsck_obj(obj);
+}
+
+static int fsck_obj_buffer(const unsigned char *sha1, enum object_type type,
+ unsigned long size, void *buffer, int *eaten)
+{
+ struct object *obj;
+ obj = parse_object_buffer(sha1, type, size, buffer, eaten);
+ if (!obj) {
+ errors_found |= ERROR_OBJECT;
+ return error("%s: object corrupt or missing", sha1_to_hex(sha1));
+ }
+ return fsck_obj(obj);
+}
+
/*
* This is the sorting chunk size: make it reasonably
* big so that we can sort well..
prepare_packed_git();
for (p = packed_git; p; p = p->next)
/* verify gives error messages itself */
- if (verify_pack(p))
+ if (verify_pack(p, fsck_obj_buffer))
errors_found |= ERROR_PACK;
-
- for (p = packed_git; p; p = p->next) {
- uint32_t j, num;
- if (open_pack_index(p))
- continue;
- num = p->num_objects;
- for (j = 0; j < num; j++)
- fsck_sha1(nth_packed_object_sha1(p, j));
- }
}
heads = 0;
diff --git a/pack-check.c b/pack-check.c
index 7ac9b3a6815f2b6f7c017b54f10e8a4b5f8070d6..3b48b86156347e35b30cd9eddab270063073478e 100644 (file)
--- a/pack-check.c
+++ b/pack-check.c
}
static int verify_packfile(struct packed_git *p,
- struct pack_window **w_curs)
+ struct pack_window **w_curs,
+ verify_fn fn)
{
off_t index_size = p->index_size;
const unsigned char *index_base = p->index_data;
else if (check_sha1_signature(entries[i].sha1, data, size, typename(type)))
err = error("packed %s from %s is corrupt",
sha1_to_hex(entries[i].sha1), p->pack_name);
+ else if (fn) {
+ int eaten = 0;
+ fn(entries[i].sha1, type, size, data, &eaten);
+ if (eaten)
+ data = NULL;
+ }
free(data);
}
free(entries);
return err;
}
-int verify_pack(struct packed_git *p)
+int verify_pack(struct packed_git *p, verify_fn fn)
{
int err = 0;
struct pack_window *w_curs = NULL;
if (!p->index_data)
return -1;
- err |= verify_packfile(p, &w_curs);
+ err |= verify_packfile(p, &w_curs, fn);
unuse_pack(&w_curs);
return err;
index 722a54e00a2cb7d9514c12f799fb1ec15930cf5d..70f3c29bea152e90257f5fc64fb128f1978a7652 100644 (file)
--- a/pack.h
+++ b/pack.h
off_t offset;
};
+
+typedef int (*verify_fn)(const unsigned char*, enum object_type, unsigned long, void*, int*);
+
extern const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, int nr_objects, const struct pack_idx_option *, unsigned char *sha1);
extern int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr);
extern int verify_pack_index(struct packed_git *);
-extern int verify_pack(struct packed_git *);
+extern int verify_pack(struct packed_git *, verify_fn fn);
extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t, unsigned char *, off_t);
extern char *index_pack_lockfile(int fd);
extern int encode_in_pack_object_header(enum object_type, uintmax_t, unsigned char *);