comparison mercurial/localrepo.py @ 13829:7b7c1d9d08ab

changegroup: unnest flookup
author Matt Mackall <mpm@selenic.com>
date Thu, 31 Mar 2011 13:56:05 -0500
parents e574207e3bcd
children 2dc6e09f2a7d
comparison
equal deleted inserted replaced
13828:b975a326aec0 13829:7b7c1d9d08ab
1477 cl = self.changelog 1477 cl = self.changelog
1478 mf = self.manifest 1478 mf = self.manifest
1479 mfs = {} # needed manifests 1479 mfs = {} # needed manifests
1480 fnodes = {} # needed file nodes 1480 fnodes = {} # needed file nodes
1481 changedfiles = set() 1481 changedfiles = set()
1482 fstate = ['', {}]
1482 count = [0] 1483 count = [0]
1483 1484
1484 # can we go through the fast path ? 1485 # can we go through the fast path ?
1485 heads.sort() 1486 heads.sort()
1486 if heads == sorted(self.heads()): 1487 if heads == sorted(self.heads()):
1513 count[0] += 1 1514 count[0] += 1
1514 self.ui.progress(_('bundling'), count[0], 1515 self.ui.progress(_('bundling'), count[0],
1515 unit=_('manifests'), total=len(mfs)) 1516 unit=_('manifests'), total=len(mfs))
1516 return mfs[x] 1517 return mfs[x]
1517 1518
1519 def flookup(revlog, x):
1520 self.ui.progress(
1521 _('bundling'), count[0], item=fstate[0],
1522 unit=_('files'), total=len(changedfiles))
1523 return fstate[1][x]
1524
1518 # Now that we have all theses utility functions to help out and 1525 # Now that we have all theses utility functions to help out and
1519 # logically divide up the task, generate the group. 1526 # logically divide up the task, generate the group.
1520 def gengroup(): 1527 def gengroup():
1521 # Create a changenode group generator that will call our functions 1528 # Create a changenode group generator that will call our functions
1522 # back to lookup the owning changenode and collect information. 1529 # back to lookup the owning changenode and collect information.
1523 for chunk in cl.group(csets, clookup): 1530 for chunk in cl.group(csets, clookup):
1524 yield chunk 1531 yield chunk
1525 efiles = len(changedfiles)
1526 self.ui.progress(_('bundling'), None) 1532 self.ui.progress(_('bundling'), None)
1527 1533
1528 # Create a generator for the manifestnodes that calls our lookup 1534 # Create a generator for the manifestnodes that calls our lookup
1529 # and data collection functions back. 1535 # and data collection functions back.
1530 count[0] = 0 1536 count[0] = 0
1533 self.ui.progress(_('bundling'), None) 1539 self.ui.progress(_('bundling'), None)
1534 1540
1535 mfs.clear() 1541 mfs.clear()
1536 1542
1537 # Go through all our files in order sorted by name. 1543 # Go through all our files in order sorted by name.
1538 for idx, fname in enumerate(sorted(changedfiles)): 1544 count[0] = 0
1545 for fname in sorted(changedfiles):
1539 filerevlog = self.file(fname) 1546 filerevlog = self.file(fname)
1540 if not len(filerevlog): 1547 if not len(filerevlog):
1541 raise util.Abort(_("empty or missing revlog for %s") % fname) 1548 raise util.Abort(_("empty or missing revlog for %s") % fname)
1542 # Toss out the filenodes that the recipient isn't really 1549 fstate[0] = fname
1543 # missing. 1550 fstate[1] = fnodes.pop(fname, {})
1544 missingfnodes = fnodes.pop(fname, {})
1545 first = True 1551 first = True
1546 1552
1547 def flookup(revlog, x): 1553 for chunk in filerevlog.group(prune(filerevlog, fstate[1]),
1548 # even though we print the same progress on
1549 # most loop iterations, put the progress call
1550 # here so that time estimates (if any) can be updated
1551 self.ui.progress(
1552 _('bundling'), idx, item=fname,
1553 unit=_('files'), total=efiles)
1554 return missingfnodes[x]
1555
1556 for chunk in filerevlog.group(prune(filerevlog, missingfnodes),
1557 flookup): 1554 flookup):
1558 if first: 1555 if first:
1559 if chunk == changegroup.closechunk(): 1556 if chunk == changegroup.closechunk():
1560 break 1557 break
1558 count[0] += 1
1561 yield changegroup.chunkheader(len(fname)) 1559 yield changegroup.chunkheader(len(fname))
1562 yield fname 1560 yield fname
1563 first = False 1561 first = False
1564 yield chunk 1562 yield chunk
1565 # Signal that no more groups are left. 1563 # Signal that no more groups are left.
1587 1585
1588 cl = self.changelog 1586 cl = self.changelog
1589 mf = self.manifest 1587 mf = self.manifest
1590 mfs = {} 1588 mfs = {}
1591 changedfiles = set() 1589 changedfiles = set()
1590 fstate = ['']
1591 count = [0]
1592 1592
1593 self.hook('preoutgoing', throw=True, source=source) 1593 self.hook('preoutgoing', throw=True, source=source)
1594 self.changegroupinfo(nodes, source) 1594 self.changegroupinfo(nodes, source)
1595 1595
1596 revset = set([cl.rev(n) for n in nodes]) 1596 revset = set([cl.rev(n) for n in nodes])
1598 def gennodelst(log): 1598 def gennodelst(log):
1599 for r in log: 1599 for r in log:
1600 if log.linkrev(r) in revset: 1600 if log.linkrev(r) in revset:
1601 yield log.node(r) 1601 yield log.node(r)
1602 1602
1603 def clookup(revlog, x):
1604 c = cl.read(x)
1605 changedfiles.update(c[3])
1606 mfs.setdefault(c[0], x)
1607 count[0] += 1
1608 self.ui.progress(_('bundling'), count[0], unit=_('changesets'))
1609 return x
1610
1611 def mlookup(revlog, x):
1612 count[0] += 1
1613 self.ui.progress(_('bundling'), count[0],
1614 unit=_('manifests'), total=len(mfs))
1615 return cl.node(revlog.linkrev(revlog.rev(x)))
1616
1617 def flookup(revlog, x):
1618 self.ui.progress(
1619 _('bundling'), count[0], item=fstate[0],
1620 total=len(changedfiles), unit=_('files'))
1621 return cl.node(revlog.linkrev(revlog.rev(x)))
1622
1603 def gengroup(): 1623 def gengroup():
1604 '''yield a sequence of changegroup chunks (strings)''' 1624 '''yield a sequence of changegroup chunks (strings)'''
1605 # construct a list of all changed files 1625 # construct a list of all changed files
1606 1626
1607 count = [0]
1608 def clookup(revlog, x):
1609 c = cl.read(x)
1610 changedfiles.update(c[3])
1611 mfs.setdefault(c[0], x)
1612 count[0] += 1
1613 self.ui.progress(_('bundling'), count[0], unit=_('changesets'))
1614 return x
1615
1616 for chunk in cl.group(nodes, clookup): 1627 for chunk in cl.group(nodes, clookup):
1617 yield chunk 1628 yield chunk
1618 efiles = len(changedfiles)
1619 changecount = count[0]
1620 self.ui.progress(_('bundling'), None) 1629 self.ui.progress(_('bundling'), None)
1621 1630
1622 count = [0] 1631 count[0] = 0
1623 def mlookup(revlog, x):
1624 count[0] += 1
1625 self.ui.progress(_('bundling'), count[0],
1626 unit=_('manifests'), total=changecount)
1627 return cl.node(revlog.linkrev(revlog.rev(x)))
1628
1629 for chunk in mf.group(gennodelst(mf), mlookup): 1632 for chunk in mf.group(gennodelst(mf), mlookup):
1630 yield chunk 1633 yield chunk
1631 self.ui.progress(_('bundling'), None) 1634 self.ui.progress(_('bundling'), None)
1632 1635
1633 for idx, fname in enumerate(sorted(changedfiles)): 1636 count[0] = 0
1637 for fname in sorted(changedfiles):
1634 filerevlog = self.file(fname) 1638 filerevlog = self.file(fname)
1635 if not len(filerevlog): 1639 if not len(filerevlog):
1636 raise util.Abort(_("empty or missing revlog for %s") % fname) 1640 raise util.Abort(_("empty or missing revlog for %s") % fname)
1641 fstate[0] = fname
1637 first = True 1642 first = True
1638 def flookup(revlog, x):
1639 self.ui.progress(
1640 _('bundling'), idx, item=fname,
1641 total=efiles, unit=_('files'))
1642 return cl.node(revlog.linkrev(revlog.rev(x)))
1643
1644 for chunk in filerevlog.group(gennodelst(filerevlog), flookup): 1643 for chunk in filerevlog.group(gennodelst(filerevlog), flookup):
1645 if first: 1644 if first:
1646 if chunk == changegroup.closechunk(): 1645 if chunk == changegroup.closechunk():
1647 break 1646 break
1647 count[0] += 1
1648 yield changegroup.chunkheader(len(fname)) 1648 yield changegroup.chunkheader(len(fname))
1649 yield fname 1649 yield fname
1650 first = False 1650 first = False
1651 yield chunk 1651 yield chunk
1652 yield changegroup.closechunk() 1652 yield changegroup.closechunk()