comparison mercurial/localrepo.py @ 13706:7beb9834d185

changegroupsubset: minor cleanups - move some variable declarations - drop some excessive comments - use standard variable naming
author Matt Mackall <mpm@selenic.com>
date Sun, 20 Mar 2011 19:43:28 -0500
parents 48d606d7192b
children 296e78744d32
comparison
equal deleted inserted replaced
13705:73cfb7a5aa56 13706:7beb9834d185
1437 1437
1438 Another wrinkle is doing the reverse, figuring out which changeset in 1438 Another wrinkle is doing the reverse, figuring out which changeset in
1439 the changegroup a particular filenode or manifestnode belongs to. 1439 the changegroup a particular filenode or manifestnode belongs to.
1440 """ 1440 """
1441 1441
1442 # Set up some initial variables
1443 # Make it easy to refer to self.changelog
1444 cl = self.changelog 1442 cl = self.changelog
1443 mf = self.manifest
1444 mfs = {} # needed manifests
1445 fnodes = {} # needed file nodes
1446
1445 # Compute the list of changesets in this changegroup. 1447 # Compute the list of changesets in this changegroup.
1446 # Some bases may turn out to be superfluous, and some heads may be 1448 # Some bases may turn out to be superfluous, and some heads may be
1447 # too. nodesbetween will return the minimal set of bases and heads 1449 # too. nodesbetween will return the minimal set of bases and heads
1448 # necessary to re-create the changegroup. 1450 # necessary to re-create the changegroup.
1449 if not bases: 1451 if not bases:
1450 bases = [nullid] 1452 bases = [nullid]
1451 msng_cl_lst, bases, heads = cl.nodesbetween(bases, heads) 1453 csets, bases, heads = cl.nodesbetween(bases, heads)
1452 1454
1453 # can we go through the fast path ? 1455 # can we go through the fast path ?
1454 heads.sort() 1456 heads.sort()
1455 allheads = self.heads() 1457 allheads = self.heads()
1456 allheads.sort() 1458 allheads.sort()
1457 if heads == allheads: 1459 if heads == allheads:
1458 return self._changegroup(msng_cl_lst, source) 1460 return self._changegroup(csets, source)
1459 1461
1460 # slow path 1462 # slow path
1461 self.hook('preoutgoing', throw=True, source=source) 1463 self.hook('preoutgoing', throw=True, source=source)
1462 1464 self.changegroupinfo(csets, source)
1463 self.changegroupinfo(msng_cl_lst, source)
1464 1465
1465 # We assume that all ancestors of bases are known 1466 # We assume that all ancestors of bases are known
1466 commonrevs = set(cl.ancestors(*[cl.rev(n) for n in bases])) 1467 commonrevs = set(cl.ancestors(*[cl.rev(n) for n in bases]))
1467
1468 # Make it easy to refer to self.manifest
1469 mnfst = self.manifest
1470 # We don't know which manifests are missing yet
1471 msng_mnfst_set = {}
1472 # Nor do we know which filenodes are missing.
1473 msng_filenode_set = {}
1474 1468
1475 # A changeset always belongs to itself, so the changenode lookup 1469 # A changeset always belongs to itself, so the changenode lookup
1476 # function for a changenode is identity. 1470 # function for a changenode is identity.
1477 def identity(x): 1471 def identity(x):
1478 return x 1472 return x
1485 # so we can include those in the changegroup too. 1479 # so we can include those in the changegroup too.
1486 # 1480 #
1487 # It also remembers which changenode each filenode belongs to. It 1481 # It also remembers which changenode each filenode belongs to. It
1488 # does this by assuming the a filenode belongs to the changenode 1482 # does this by assuming the a filenode belongs to the changenode
1489 # the first manifest that references it belongs to. 1483 # the first manifest that references it belongs to.
1490 def collect_msng_filenodes(mnfstnode): 1484 def collect(mannode):
1491 r = mnfst.rev(mnfstnode) 1485 r = mf.rev(mannode)
1492 if mnfst.deltaparent(r) in mnfst.parentrevs(r): 1486 if mf.deltaparent(r) in mf.parentrevs(r):
1493 # If the previous rev is one of the parents, 1487 # If the previous rev is one of the parents,
1494 # we only need to see a diff. 1488 # we only need to see a diff.
1495 deltamf = mnfst.readdelta(mnfstnode) 1489 deltamf = mf.readdelta(mannode)
1496 # For each line in the delta 1490 # For each line in the delta
1497 for f, fnode in deltamf.iteritems(): 1491 for f, fnode in deltamf.iteritems():
1498 # And if the file is in the list of files we care 1492 # And if the file is in the list of files we care
1499 # about. 1493 # about.
1500 if f in changedfiles: 1494 if f in changedfiles:
1501 # Get the changenode this manifest belongs to 1495 # Get the changenode this manifest belongs to
1502 clnode = msng_mnfst_set[mnfstnode] 1496 clnode = mfs[mannode]
1503 # Create the set of filenodes for the file if 1497 # Create the set of filenodes for the file if
1504 # there isn't one already. 1498 # there isn't one already.
1505 ndset = msng_filenode_set.setdefault(f, {}) 1499 ndset = fnodes.setdefault(f, {})
1506 # And set the filenode's changelog node to the 1500 # And set the filenode's changelog node to the
1507 # manifest's if it hasn't been set already. 1501 # manifest's if it hasn't been set already.
1508 ndset.setdefault(fnode, clnode) 1502 ndset.setdefault(fnode, clnode)
1509 else: 1503 else:
1510 # Otherwise we need a full manifest. 1504 # Otherwise we need a full manifest.
1511 m = mnfst.read(mnfstnode) 1505 m = mf.read(mannode)
1512 # For every file in we care about. 1506 # For every file in we care about.
1513 for f in changedfiles: 1507 for f in changedfiles:
1514 fnode = m.get(f, None) 1508 fnode = m.get(f, None)
1515 # If it's in the manifest 1509 # If it's in the manifest
1516 if fnode is not None: 1510 if fnode is not None:
1517 # See comments above. 1511 # See comments above.
1518 clnode = msng_mnfst_set[mnfstnode] 1512 clnode = mfs[mannode]
1519 ndset = msng_filenode_set.setdefault(f, {}) 1513 ndset = fnodes.setdefault(f, {})
1520 ndset.setdefault(fnode, clnode) 1514 ndset.setdefault(fnode, clnode)
1521 return collect_msng_filenodes 1515 return collect
1522 1516
1523 # If we determine that a particular file or manifest node must be a 1517 # If we determine that a particular file or manifest node must be a
1524 # node that the recipient of the changegroup will already have, we can 1518 # node that the recipient of the changegroup will already have, we can
1525 # also assume the recipient will have all the parents. This function 1519 # also assume the recipient will have all the parents. This function
1526 # prunes them from the set of missing nodes. 1520 # prunes them from the set of missing nodes.
1541 # Now that we have all theses utility functions to help out and 1535 # Now that we have all theses utility functions to help out and
1542 # logically divide up the task, generate the group. 1536 # logically divide up the task, generate the group.
1543 def gengroup(): 1537 def gengroup():
1544 # The set of changed files starts empty. 1538 # The set of changed files starts empty.
1545 changedfiles = set() 1539 changedfiles = set()
1546 collect = changegroup.collector(cl, msng_mnfst_set, changedfiles) 1540 collect = changegroup.collector(cl, mfs, changedfiles)
1547 1541
1548 # Create a changenode group generator that will call our functions 1542 # Create a changenode group generator that will call our functions
1549 # back to lookup the owning changenode and collect information. 1543 # back to lookup the owning changenode and collect information.
1550 group = cl.group(msng_cl_lst, identity, collect) 1544 group = cl.group(csets, identity, collect)
1551 for cnt, chnk in enumerate(group): 1545 for cnt, chnk in enumerate(group):
1552 yield chnk 1546 yield chnk
1553 # revlog.group yields three entries per node, so 1547 # revlog.group yields three entries per node, so
1554 # dividing by 3 gives an approximation of how many 1548 # dividing by 3 gives an approximation of how many
1555 # nodes have been processed. 1549 # nodes have been processed.
1556 self.ui.progress(_('bundling'), cnt / 3, 1550 self.ui.progress(_('bundling'), cnt / 3,
1557 unit=_('changesets')) 1551 unit=_('changesets'))
1558 changecount = cnt / 3 1552 changecount = cnt / 3
1559 self.ui.progress(_('bundling'), None) 1553 self.ui.progress(_('bundling'), None)
1560 1554
1561 prune(mnfst, msng_mnfst_set) 1555 prune(mf, mfs)
1562 msng_mnfst_lst = msng_mnfst_set.keys()
1563 # Sort the manifestnodes by revision number.
1564 msng_mnfst_lst.sort(key=mnfst.rev)
1565 # Create a generator for the manifestnodes that calls our lookup 1556 # Create a generator for the manifestnodes that calls our lookup
1566 # and data collection functions back. 1557 # and data collection functions back.
1567 group = mnfst.group(msng_mnfst_lst, 1558 group = mf.group(sorted(mfs, key=mf.rev),
1568 lambda mnode: msng_mnfst_set[mnode], 1559 lambda mnode: mfs[mnode],
1569 filenode_collector(changedfiles)) 1560 filenode_collector(changedfiles))
1570 efiles = {} 1561 efiles = {}
1571 for cnt, chnk in enumerate(group): 1562 for cnt, chnk in enumerate(group):
1572 if cnt % 3 == 1: 1563 if cnt % 3 == 1:
1573 mnode = chnk[:20] 1564 mnode = chnk[:20]
1574 efiles.update(mnfst.readdelta(mnode)) 1565 efiles.update(mf.readdelta(mnode))
1575 yield chnk 1566 yield chnk
1576 # see above comment for why we divide by 3 1567 # see above comment for why we divide by 3
1577 self.ui.progress(_('bundling'), cnt / 3, 1568 self.ui.progress(_('bundling'), cnt / 3,
1578 unit=_('manifests'), total=changecount) 1569 unit=_('manifests'), total=changecount)
1579 self.ui.progress(_('bundling'), None) 1570 self.ui.progress(_('bundling'), None)
1580 efiles = len(efiles) 1571 efiles = len(efiles)
1581 1572
1582 # These are no longer needed, dereference and toss the memory for 1573 mfs.clear()
1583 # them.
1584 msng_mnfst_lst = None
1585 msng_mnfst_set.clear()
1586 1574
1587 # Go through all our files in order sorted by name. 1575 # Go through all our files in order sorted by name.
1588 for idx, fname in enumerate(sorted(changedfiles)): 1576 for idx, fname in enumerate(sorted(changedfiles)):
1589 filerevlog = self.file(fname) 1577 filerevlog = self.file(fname)
1590 if not len(filerevlog): 1578 if not len(filerevlog):
1591 raise util.Abort(_("empty or missing revlog for %s") % fname) 1579 raise util.Abort(_("empty or missing revlog for %s") % fname)
1592 # Toss out the filenodes that the recipient isn't really 1580 # Toss out the filenodes that the recipient isn't really
1593 # missing. 1581 # missing.
1594 missingfnodes = msng_filenode_set.pop(fname, {}) 1582 missingfnodes = fnodes.pop(fname, {})
1595 prune(filerevlog, missingfnodes) 1583 prune(filerevlog, missingfnodes)
1596 # If any filenodes are left, generate the group for them, 1584 # If any filenodes are left, generate the group for them,
1597 # otherwise don't bother. 1585 # otherwise don't bother.
1598 if missingfnodes: 1586 if missingfnodes:
1599 yield changegroup.chunkheader(len(fname)) 1587 yield changegroup.chunkheader(len(fname))
1616 yield chnk 1604 yield chnk
1617 # Signal that no more groups are left. 1605 # Signal that no more groups are left.
1618 yield changegroup.closechunk() 1606 yield changegroup.closechunk()
1619 self.ui.progress(_('bundling'), None) 1607 self.ui.progress(_('bundling'), None)
1620 1608
1621 if msng_cl_lst: 1609 if csets:
1622 self.hook('outgoing', node=hex(msng_cl_lst[0]), source=source) 1610 self.hook('outgoing', node=hex(csets[0]), source=source)
1623 1611
1624 return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN') 1612 return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN')
1625 1613
1626 def changegroup(self, basenodes, source): 1614 def changegroup(self, basenodes, source):
1627 # to avoid a race we use changegroupsubset() (issue1320) 1615 # to avoid a race we use changegroupsubset() (issue1320)