##// END OF EJS Templates
Fix memory leak when using hg commands over http repositories...
Fix memory leak when using hg commands over http repositories When using hg commands over an http repository in a long running process, a httphandler instance is leaked for each command, because of a loop handler.parent -> OpenerDirector and OpenerDirector.handlers -> handler which is not handled by Python's gc. Discussion on #mercurial concluded that removing the __del__ method solved the problem.

File last commit:

r10602:94145b53 default
r12391:ca5fd84d stable
Show More
graphmod.py
122 lines | 3.8 KiB | text/x-python | PythonLexer
Dirkjan Ochtman
add graph page to hgweb
r6691 # Revision graph generator for Mercurial
#
# Copyright 2008 Dirkjan Ochtman <dirkjan@ochtman.nl>
# Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 """supports walking the history as DAGs suitable for graphical output
The most basic format we use is that of::
(id, type, data, [parentids])
The node and parent ids are arbitrary integers which identify a node in the
context of the graph returned. Type is a constant specifying the node type.
Data depends on type.
"""
from mercurial.node import nullrev
CHANGESET = 'C'
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836 def revisions(repo, start, stop):
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836
This generator function walks through the revision history from revision
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 start to revision stop (which must be less than or equal to start). It
returns a tuple for each node. The node and parent ids are arbitrary
integers which identify a node in the context of the graph returned.
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836 """
cur = start
while cur >= stop:
ctx = repo[cur]
parents = [p.rev() for p in ctx.parents() if p.rev() != nullrev]
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 yield (cur, CHANGESET, ctx, sorted(parents))
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836 cur -= 1
Nicolas Dumazet
cmdutil: replace sys.maxint with None as default value in loglimit...
r10111 def filerevs(repo, path, start, stop, limit=None):
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 """file cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836
This generator function walks through the revision history of a single
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 file from revision start down to revision stop.
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836 """
filerev = len(repo.file(path)) - 1
Nicolas Dumazet
graphlog: fix output when both a limit and a path are provided...
r10084 rev = stop + 1
count = 0
while filerev >= 0 and rev > stop:
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836 fctx = repo.filectx(path, fileid=filerev)
parents = [f.linkrev() for f in fctx.parents() if f.path() == path]
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 rev = fctx.rev()
if rev <= start:
Dirkjan Ochtman
graphlog: don't pass filectxs to the templater (issue1896)
r9727 yield (rev, CHANGESET, fctx.changectx(), sorted(parents))
Nicolas Dumazet
graphlog: fix output when both a limit and a path are provided...
r10084 count += 1
if count == limit:
break
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836 filerev -= 1
Peter Arrenbrecht
graphmod/graphlog: extract nodelistwalk
r8837 def nodes(repo, nodes):
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
This generator function walks the given nodes. It only returns parents
that are in nodes, too.
"""
Peter Arrenbrecht
graphmod/graphlog: extract nodelistwalk
r8837 include = set(nodes)
for node in nodes:
ctx = repo[node]
parents = [p.rev() for p in ctx.parents() if p.node() in include]
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
Peter Arrenbrecht
graphmod/graphlog: extract nodelistwalk
r8837
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 def colored(dag):
"""annotates a DAG with colored edge information
For each DAG node this function emits tuples::
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 (id, type, data, (col, color), [(col, nextcol, color)])
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 with the following new elements:
Peter Arrenbrecht
graphmod: code cleanup and doc fix
r8835 - Tuple (col, color) with column and color index for the current node
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 - A list of tuples indicating the edges between the current node and its
parents.
Dirkjan Ochtman
add graph page to hgweb
r6691 """
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 seen = []
Dirkjan Ochtman
add graph page to hgweb
r6691 colors = {}
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 newcolor = 1
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 for (cur, type, data, parents) in dag:
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 # Compute seen and next
if cur not in seen:
seen.append(cur) # new head
colors[cur] = newcolor
newcolor += 1
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 col = seen.index(cur)
color = colors.pop(cur)
next = seen[:]
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 # Add parents to next
Dirkjan Ochtman
add graph page to hgweb
r6691 addparents = [p for p in parents if p not in next]
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 next[col:col + 1] = addparents
Dirkjan Ochtman
add graph page to hgweb
r6691
# Set colors for the parents
for i, p in enumerate(addparents):
if not i:
colors[p] = color
else:
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 colors[p] = newcolor
newcolor += 1
Dirkjan Ochtman
add graph page to hgweb
r6691
# Add edges to the graph
edges = []
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 for ecol, eid in enumerate(seen):
if eid in next:
edges.append((ecol, next.index(eid), colors[eid]))
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 elif eid == cur:
Dirkjan Ochtman
add graph page to hgweb
r6691 for p in parents:
Benoit Boissinot
hgweb/graph: edge should be same color as the destination
r10602 edges.append((ecol, next.index(p), color))
Dirkjan Ochtman
add graph page to hgweb
r6691
# Yield and move on
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 yield (cur, type, data, (col, color), edges)
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 seen = next