author | Junio C Hamano <gitster@pobox.com> | |
Tue, 12 Jan 2010 08:56:15 +0000 (00:56 -0800) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Tue, 12 Jan 2010 08:58:13 +0000 (00:58 -0800) |
* jc/maint-1.6.4-grep-lookahead:
grep: optimize built-in grep by skipping lines that do not hit
This needs to be an evil merge as fixmatch() changed signature since
5183bf6 (grep: Allow case insensitive search of fixed-strings,
2009-11-06).
Signed-off-by: Junio C Hamano <gitster@pobox.com>
grep: optimize built-in grep by skipping lines that do not hit
This needs to be an evil merge as fixmatch() changed signature since
5183bf6 (grep: Allow case insensitive search of fixed-strings,
2009-11-06).
Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 | 2 | |||
---|---|---|---|---|
grep.c | patch | | diff1 | | diff2 | | blob | history |
diff --cc grep.c
index bdadf2c0ccfafc18011beee3bc05754860392523,03ffcd4042e95b521e2aed03ecf2ae6d65fef41c..62723da1340d8b1e7ddbe00544dadbfc5abf4c8c
+++ b/grep.c
}
}
- hit = !fixmatch(p->pattern, bol, &m);
+ static int should_lookahead(struct grep_opt *opt)
+ {
+ struct grep_pat *p;
+
+ if (opt->extended)
+ return 0; /* punt for too complex stuff */
+ if (opt->invert)
+ return 0;
+ for (p = opt->pattern_list; p; p = p->next) {
+ if (p->token != GREP_PATTERN)
+ return 0; /* punt for "header only" and stuff */
+ }
+ return 1;
+ }
+
+ static int look_ahead(struct grep_opt *opt,
+ unsigned long *left_p,
+ unsigned *lno_p,
+ char **bol_p)
+ {
+ unsigned lno = *lno_p;
+ char *bol = *bol_p;
+ struct grep_pat *p;
+ char *sp, *last_bol;
+ regoff_t earliest = -1;
+
+ for (p = opt->pattern_list; p; p = p->next) {
+ int hit;
+ regmatch_t m;
+
+ if (p->fixed)
++ hit = !fixmatch(p->pattern, bol, p->ignore_case, &m);
+ else
+ hit = !regexec(&p->regexp, bol, 1, &m, 0);
+ if (!hit || m.rm_so < 0 || m.rm_eo < 0)
+ continue;
+ if (earliest < 0 || m.rm_so < earliest)
+ earliest = m.rm_so;
+ }
+
+ if (earliest < 0) {
+ *bol_p = bol + *left_p;
+ *left_p = 0;
+ return 1;
+ }
+ for (sp = bol + earliest; bol < sp && sp[-1] != '\n'; sp--)
+ ; /* find the beginning of the line */
+ last_bol = sp;
+
+ for (sp = bol; sp < last_bol; sp++) {
+ if (*sp == '\n')
+ lno++;
+ }
+ *left_p -= last_bol - bol;
+ *bol_p = last_bol;
+ *lno_p = lno;
+ return 0;
+ }
+
static int grep_buffer_1(struct grep_opt *opt, const char *name,
char *buf, unsigned long size, int collect_hits)
{