comparison mercurial/localrepo.py @ 13116:c36dad4f6e54

bundle progress: offer best-guess deterministic progress information This uses the same strategy as progress for pulls, estimating manifests based on changeset count and estimating file count by files list in each changeset.
author Augie Fackler <durin42@gmail.com>
date Fri, 10 Dec 2010 13:30:37 -0600
parents a98a90023261
children 6320101a638c
comparison
equal deleted inserted replaced
13115:bda5f35fbf67 13116:c36dad4f6e54
1499 # Create a changenode group generator that will call our functions 1499 # Create a changenode group generator that will call our functions
1500 # back to lookup the owning changenode and collect information. 1500 # back to lookup the owning changenode and collect information.
1501 group = cl.group(msng_cl_lst, identity, collect) 1501 group = cl.group(msng_cl_lst, identity, collect)
1502 for cnt, chnk in enumerate(group): 1502 for cnt, chnk in enumerate(group):
1503 yield chnk 1503 yield chnk
1504 self.ui.progress(_('bundling changes'), cnt, unit=_('chunks')) 1504 # revlog.group yields three entries per node, so
1505 self.ui.progress(_('bundling changes'), None) 1505 # dividing by 3 gives an approximation of how many
1506 # nodes have been processed.
1507 self.ui.progress(_('bundling'), cnt / 3,
1508 unit=_('changesets'))
1509 changecount = cnt / 3
1510 self.ui.progress(_('bundling'), None)
1506 1511
1507 prune(mnfst, msng_mnfst_set) 1512 prune(mnfst, msng_mnfst_set)
1508 add_extra_nodes(1, msng_mnfst_set) 1513 add_extra_nodes(1, msng_mnfst_set)
1509 msng_mnfst_lst = msng_mnfst_set.keys() 1514 msng_mnfst_lst = msng_mnfst_set.keys()
1510 # Sort the manifestnodes by revision number. 1515 # Sort the manifestnodes by revision number.
1512 # Create a generator for the manifestnodes that calls our lookup 1517 # Create a generator for the manifestnodes that calls our lookup
1513 # and data collection functions back. 1518 # and data collection functions back.
1514 group = mnfst.group(msng_mnfst_lst, 1519 group = mnfst.group(msng_mnfst_lst,
1515 lambda mnode: msng_mnfst_set[mnode], 1520 lambda mnode: msng_mnfst_set[mnode],
1516 filenode_collector(changedfiles)) 1521 filenode_collector(changedfiles))
1522 efiles = {}
1517 for cnt, chnk in enumerate(group): 1523 for cnt, chnk in enumerate(group):
1524 if cnt % 3 == 1:
1525 mnode = chnk[:20]
1526 efiles.update(mnfst.readdelta(mnode))
1518 yield chnk 1527 yield chnk
1519 self.ui.progress(_('bundling manifests'), cnt, unit=_('chunks')) 1528 # see above comment for why we divide by 3
1520 self.ui.progress(_('bundling manifests'), None) 1529 self.ui.progress(_('bundling'), cnt / 3,
1530 unit=_('manifests'), total=changecount)
1531 self.ui.progress(_('bundling'), None)
1532 efiles = len(efiles)
1521 1533
1522 # These are no longer needed, dereference and toss the memory for 1534 # These are no longer needed, dereference and toss the memory for
1523 # them. 1535 # them.
1524 msng_mnfst_lst = None 1536 msng_mnfst_lst = None
1525 msng_mnfst_set.clear() 1537 msng_mnfst_set.clear()
1529 if isinstance(fname, int): 1541 if isinstance(fname, int):
1530 continue 1542 continue
1531 msng_filenode_set.setdefault(fname, {}) 1543 msng_filenode_set.setdefault(fname, {})
1532 changedfiles.add(fname) 1544 changedfiles.add(fname)
1533 # Go through all our files in order sorted by name. 1545 # Go through all our files in order sorted by name.
1534 cnt = 0 1546 for idx, fname in enumerate(sorted(changedfiles)):
1535 for fname in sorted(changedfiles):
1536 filerevlog = self.file(fname) 1547 filerevlog = self.file(fname)
1537 if not len(filerevlog): 1548 if not len(filerevlog):
1538 raise util.Abort(_("empty or missing revlog for %s") % fname) 1549 raise util.Abort(_("empty or missing revlog for %s") % fname)
1539 # Toss out the filenodes that the recipient isn't really 1550 # Toss out the filenodes that the recipient isn't really
1540 # missing. 1551 # missing.
1553 # lookup function as we need to collect no information 1564 # lookup function as we need to collect no information
1554 # from filenodes. 1565 # from filenodes.
1555 group = filerevlog.group(nodeiter, 1566 group = filerevlog.group(nodeiter,
1556 lambda fnode: missingfnodes[fnode]) 1567 lambda fnode: missingfnodes[fnode])
1557 for chnk in group: 1568 for chnk in group:
1569 # even though we print the same progress on
1570 # most loop iterations, put the progress call
1571 # here so that time estimates (if any) can be updated
1558 self.ui.progress( 1572 self.ui.progress(
1559 _('bundling files'), cnt, item=fname, unit=_('chunks')) 1573 _('bundling'), idx, item=fname,
1560 cnt += 1 1574 unit=_('files'), total=efiles)
1561 yield chnk 1575 yield chnk
1562 # Signal that no more groups are left. 1576 # Signal that no more groups are left.
1563 yield changegroup.closechunk() 1577 yield changegroup.closechunk()
1564 self.ui.progress(_('bundling files'), None) 1578 self.ui.progress(_('bundling'), None)
1565 1579
1566 if msng_cl_lst: 1580 if msng_cl_lst:
1567 self.hook('outgoing', node=hex(msng_cl_lst[0]), source=source) 1581 self.hook('outgoing', node=hex(msng_cl_lst[0]), source=source)
1568 1582
1569 return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN') 1583 return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN')
1607 changedfiles = set() 1621 changedfiles = set()
1608 mmfs = {} 1622 mmfs = {}
1609 collect = changegroup.collector(cl, mmfs, changedfiles) 1623 collect = changegroup.collector(cl, mmfs, changedfiles)
1610 1624
1611 for cnt, chnk in enumerate(cl.group(nodes, identity, collect)): 1625 for cnt, chnk in enumerate(cl.group(nodes, identity, collect)):
1612 self.ui.progress(_('bundling changes'), cnt, unit=_('chunks')) 1626 # revlog.group yields three entries per node, so
1627 # dividing by 3 gives an approximation of how many
1628 # nodes have been processed.
1629 self.ui.progress(_('bundling'), cnt / 3, unit=_('changesets'))
1613 yield chnk 1630 yield chnk
1614 self.ui.progress(_('bundling changes'), None) 1631 changecount = cnt / 3
1632 self.ui.progress(_('bundling'), None)
1615 1633
1616 mnfst = self.manifest 1634 mnfst = self.manifest
1617 nodeiter = gennodelst(mnfst) 1635 nodeiter = gennodelst(mnfst)
1636 efiles = {}
1618 for cnt, chnk in enumerate(mnfst.group(nodeiter, 1637 for cnt, chnk in enumerate(mnfst.group(nodeiter,
1619 lookuplinkrev_func(mnfst))): 1638 lookuplinkrev_func(mnfst))):
1620 self.ui.progress(_('bundling manifests'), cnt, unit=_('chunks')) 1639 if cnt % 3 == 1:
1640 mnode = chnk[:20]
1641 efiles.update(mnfst.readdelta(mnode))
1642 # see above comment for why we divide by 3
1643 self.ui.progress(_('bundling'), cnt / 3,
1644 unit=_('manifests'), total=changecount)
1621 yield chnk 1645 yield chnk
1622 self.ui.progress(_('bundling manifests'), None) 1646 efiles = len(efiles)
1623 1647 self.ui.progress(_('bundling'), None)
1624 cnt = 0 1648
1625 for fname in sorted(changedfiles): 1649 for idx, fname in enumerate(sorted(changedfiles)):
1626 filerevlog = self.file(fname) 1650 filerevlog = self.file(fname)
1627 if not len(filerevlog): 1651 if not len(filerevlog):
1628 raise util.Abort(_("empty or missing revlog for %s") % fname) 1652 raise util.Abort(_("empty or missing revlog for %s") % fname)
1629 nodeiter = gennodelst(filerevlog) 1653 nodeiter = gennodelst(filerevlog)
1630 nodeiter = list(nodeiter) 1654 nodeiter = list(nodeiter)
1632 yield changegroup.chunkheader(len(fname)) 1656 yield changegroup.chunkheader(len(fname))
1633 yield fname 1657 yield fname
1634 lookup = lookuplinkrev_func(filerevlog) 1658 lookup = lookuplinkrev_func(filerevlog)
1635 for chnk in filerevlog.group(nodeiter, lookup): 1659 for chnk in filerevlog.group(nodeiter, lookup):
1636 self.ui.progress( 1660 self.ui.progress(
1637 _('bundling files'), cnt, item=fname, unit=_('chunks')) 1661 _('bundling'), idx, item=fname,
1638 cnt += 1 1662 total=efiles, unit=_('files'))
1639 yield chnk 1663 yield chnk
1640 self.ui.progress(_('bundling files'), None) 1664 self.ui.progress(_('bundling'), None)
1641 1665
1642 yield changegroup.closechunk() 1666 yield changegroup.closechunk()
1643 1667
1644 if nodes: 1668 if nodes:
1645 self.hook('outgoing', node=hex(nodes[0]), source=source) 1669 self.hook('outgoing', node=hex(nodes[0]), source=source)