Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/util.py @ 4371:d7ad1e42a368
util._matcher: speed up regexp matching.
In 4babaa52badf, Benoit made a change that substantially slows matching
when a big .hgignore file is in play, because it calls into the regexp
matching engine potentially hundreds of times per file to be matched.
I've partly rolled back his change, so that we only call into the matcher
once per file, but preserved the ability to report a meaningful error
message if there's a syntax error in the regexp.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Tue, 24 Apr 2007 10:53:25 -0700 |
parents | 8b4d4f84b739 |
children | e33ad7cea15f |
comparison
equal
deleted
inserted
replaced
4370:6af107c742bf | 4371:d7ad1e42a368 |
---|---|
467 | 467 |
468 def matchfn(pats, tail): | 468 def matchfn(pats, tail): |
469 """build a matching function from a set of patterns""" | 469 """build a matching function from a set of patterns""" |
470 if not pats: | 470 if not pats: |
471 return | 471 return |
472 matches = [] | 472 try: |
473 for k, p in pats: | 473 pat = '(?:%s)' % '|'.join([regex(k, p, tail) for (k, p) in pats]) |
474 try: | 474 return re.compile(pat).match |
475 pat = '(?:%s)' % regex(k, p, tail) | 475 except re.error: |
476 matches.append(re.compile(pat).match) | 476 for k, p in pats: |
477 except re.error: | 477 try: |
478 if src: raise Abort("%s: invalid pattern (%s): %s" % (src, k, p)) | 478 re.compile('(?:%s)' % regex(k, p, tail)) |
479 else: raise Abort("invalid pattern (%s): %s" % (k, p)) | 479 except re.error: |
480 | 480 if src: |
481 def buildfn(text): | 481 raise Abort("%s: invalid pattern (%s): %s" % |
482 for m in matches: | 482 (src, k, p)) |
483 r = m(text) | 483 else: |
484 if r: | 484 raise Abort("invalid pattern (%s): %s" % (k, p)) |
485 return r | 485 raise Abort("invalid pattern") |
486 | |
487 return buildfn | |
488 | 486 |
489 def globprefix(pat): | 487 def globprefix(pat): |
490 '''return the non-glob prefix of a path, e.g. foo/* -> foo''' | 488 '''return the non-glob prefix of a path, e.g. foo/* -> foo''' |
491 root = [] | 489 root = [] |
492 for p in pat.split('/'): | 490 for p in pat.split('/'): |