@matheusbsbs / matheus-bagliano / commits / 101d15e097
Fork 0

Introduce for_each_recent_reflog_ent().

This can be used to scan only the last few kilobytes of a reflog, as a cheap optimization when the data you are looking for is likely to be found near the end of it. The caller is expected to fall back to the full scan if that is not the case. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Jan 19, 2009 at 22:18 UTC 101d15e09712a0183db99d228d975c62970654cf
3 files changed +24 -2
refs.c
+16 -1
@@ -1453,7 +1453,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
1453 return 1;
1454 }
1455
1456 -int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
1456 +int for_each_recent_reflog_ent(const char *ref, each_reflog_ent_fn fn, long ofs, void *cb_data)
1457 {
1458 const char *logfile;
1459 FILE *logfp;
@@ -1464,6 +1464,16 @@ int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
1464 logfp = fopen(logfile, "r");
1465 if (!logfp)
1466 return -1;
1467 +
1468 + if (ofs) {
1469 + struct stat statbuf;
1470 + if (fstat(fileno(logfp), &statbuf) ||
1471 + statbuf.st_size < ofs ||
1472 + fseek(logfp, -ofs, SEEK_END) ||
1473 + fgets(buf, sizeof(buf), logfp))
1474 + return -1;
1475 + }
1476 +
1477 while (fgets(buf, sizeof(buf), logfp)) {
1478 unsigned char osha1[20], nsha1[20];
1479 char *email_end, *message;
@@ -1497,6 +1507,11 @@ int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
1507 return ret;
1508 }
1509
1510 +int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
1511 +{
1512 + return for_each_recent_reflog_ent(ref, fn, 0, cb_data);
1513 +}
1514 +
1515 static int do_for_each_reflog(const char *base, each_ref_fn fn, void *cb_data)
1516 {
1517 DIR *dir = opendir(git_path("logs/%s", base));
refs.h
+1
@@ -60,6 +60,7 @@ extern int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned
60 /* iterate over reflog entries */
61 typedef int each_reflog_ent_fn(unsigned char *osha1, unsigned char *nsha1, const char *, unsigned long, int, const char *, void *);
62 int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data);
63 +int for_each_recent_reflog_ent(const char *ref, each_reflog_ent_fn fn, long, void *cb_data);
64
65 /*
66 * Calls the specified function for each reflog file until it returns nonzero,
sha1_name.c
+7 -1
@@ -775,7 +775,13 @@ int interpret_nth_last_branch(const char *name, struct strbuf *buf)
775 strbuf_init(&cb.buf[i], 20);
776 cb.cnt = 0;
777 retval = 0;
778 - for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
778 + for_each_recent_reflog_ent("HEAD", grab_nth_branch_switch, 40960, &cb);
779 + if (cb.cnt < nth) {
780 + cb.cnt = 0;
781 + for (i = 0; i < nth; i++)
782 + strbuf_release(&cb.buf[i]);
783 + for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
784 + }
785 if (cb.cnt < nth)
786 goto release_return;
787 i = cb.cnt % nth;