comparison mercurial/util.py @ 4369: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 ec64f263e49a
children e33ad7cea15f
comparison
equal deleted inserted replaced
4368:6af107c742bf 4369: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('/'):