# HG changeset patch # User Matt Mackall # Date 1247177407 18000 # Node ID 431462bd84782c34670d53d8e6c8d907e408cf27 # Parent 47bc92755b9598c8595397a5e27a9c2bd303fc69 fix memory usage of revlog caches by limiting cache size [issue1639] diff -r 47bc92755b95 -r 431462bd8478 mercurial/commands.py --- a/mercurial/commands.py Thu Jul 09 11:59:12 2009 +0200 +++ b/mercurial/commands.py Thu Jul 09 17:10:07 2009 -0500 @@ -1206,18 +1206,7 @@ if opts.get('print0'): sep = eol = '\0' - fcache = {} - forder = [] - def getfile(fn): - if fn not in fcache: - if len(fcache) > 20: - del fcache[forder.pop(0)] - fcache[fn] = repo.file(fn) - else: - forder.remove(fn) - - forder.append(fn) - return fcache[fn] + getfile = util.lrucachefunc(repo.file) def matchlines(body): begin = 0 diff -r 47bc92755b95 -r 431462bd8478 mercurial/context.py --- a/mercurial/context.py Thu Jul 09 11:59:12 2009 +0200 +++ b/mercurial/context.py Thu Jul 09 17:10:07 2009 -0500 @@ -379,11 +379,11 @@ child[0][b1:b2] = parent[0][a1:a2] return child - getlog = util.cachefunc(lambda x: self._repo.file(x)) + getlog = util.lrucachefunc(lambda x: self._repo.file(x)) def getctx(path, fileid): log = path == self._path and self._filelog or getlog(path) return filectx(self._repo, path, fileid=fileid, filelog=log) - getctx = util.cachefunc(getctx) + getctx = util.lrucachefunc(getctx) def parents(f): # we want to reuse filectx objects as much as possible diff -r 47bc92755b95 -r 431462bd8478 mercurial/copies.py --- a/mercurial/copies.py Thu Jul 09 11:59:12 2009 +0200 +++ b/mercurial/copies.py Thu Jul 09 17:10:07 2009 -0500 @@ -120,8 +120,8 @@ return c1.filectx(f) return c2.filectx(f) return repo.filectx(f, fileid=n) - ctx = util.cachefunc(makectx) + ctx = util.lrucachefunc(makectx) copy = {} fullcopy = {} diverge = {} diff -r 47bc92755b95 -r 431462bd8478 mercurial/util.py --- a/mercurial/util.py Thu Jul 09 11:59:12 2009 +0200 +++ b/mercurial/util.py Thu Jul 09 17:10:07 2009 -0500 @@ -115,6 +115,33 @@ return f +def lrucachefunc(func): + '''cache most recent results of function calls''' + cache = {} + order = [] + if func.func_code.co_argcount == 1: + def f(arg): + if arg not in cache: + if len(cache) > 20: + del cache[order.pop(0)] + cache[arg] = func(arg) + else: + order.remove(arg) + order.append(arg) + return cache[arg] + else: + def f(*args): + if args not in cache: + if len(cache) > 20: + del cache[order.pop(0)] + cache[args] = func(*args) + else: + order.remove(args) + order.append(args) + return cache[args] + + return f + class propertycache(object): def __init__(self, func): self.func = func