##// END OF EJS Templates
A new ancestor algorithm...
mpm@selenic.com -
r147:b6d8ed7a default
parent child Browse files
Show More
@@ -8,7 +8,7 b''
8 # This software may be used and distributed according to the terms
8 # This software may be used and distributed according to the terms
9 # of the GNU General Public License, incorporated herein by reference.
9 # of the GNU General Public License, incorporated herein by reference.
10
10
11 import zlib, struct, sha, os, tempfile, binascii
11 import zlib, struct, sha, os, tempfile, binascii, heapq
12 from mercurial import mdiff
12 from mercurial import mdiff
13
13
14 def hex(node): return binascii.hexlify(node)
14 def hex(node): return binascii.hexlify(node)
@@ -276,38 +276,42 b' class revlog:'
276 return node
276 return node
277
277
278 def ancestor(self, a, b):
278 def ancestor(self, a, b):
279 def expand(list, map):
279 # calculate the distance of every node from root
280 a = []
280 dist = {nullid: 0}
281 while list:
281 for i in xrange(self.count()):
282 n = list.pop(0)
282 n = self.node(i)
283 map[n] = 1
283 p1, p2 = self.parents(n)
284 yield n
284 dist[n] = max(dist[p1], dist[p2]) + 1
285 for p in self.parents(n):
285
286 if p != nullid and p not in map:
286 # traverse ancestors in order of decreasing distance from root
287 list.append(p)
287 def ancestors(node):
288 yield nullid
288 # we store negative distances because heap returns smallest member
289 h = [(-dist[node], node)]
290 seen = {}
291 earliest = self.count()
292 while h:
293 d, n = heapq.heappop(h)
294 r = self.rev(n)
295 if n not in seen:
296 seen[n] = 1
297 yield (-d, n)
298 for p in self.parents(n):
299 heapq.heappush(h, (-dist[p], p))
289
300
290 amap = {}
301 x = ancestors(a)
291 bmap = {}
302 y = ancestors(b)
292 ag = expand([a], amap)
303 lx = x.next()
293 bg = expand([b], bmap)
304 ly = y.next()
294 adone = bdone = 0
295
305
296 while not adone or not bdone:
306 # increment each ancestor list until it is closer to root than
297 if not adone:
307 # the other, or they match
298 an = ag.next()
308 while 1:
299 if an == nullid:
309 if lx == ly:
300 adone = 1
310 return lx[1]
301 elif an in bmap:
311 elif lx < ly:
302 return an
312 ly = y.next()
303 if not bdone:
313 elif lx > ly:
304 bn = bg.next()
314 lx = x.next()
305 if bn == nullid:
306 bdone = 1
307 elif bn in amap:
308 return bn
309
310 return nullid
311
315
312 def group(self, linkmap):
316 def group(self, linkmap):
313 # given a list of changeset revs, return a set of deltas and
317 # given a list of changeset revs, return a set of deltas and
General Comments 0
You need to be logged in to leave comments. Login now