~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/graph.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-03-17 07:05:37 UTC
  • mfrom: (4152.1.2 branch.stacked.streams)
  • Revision ID: pqm@pqm.ubuntu.com-20090317070537-zaud24vjs2szna87
(robertc) Add client-side streaming from stacked branches (over
        bzr:// protocols) when the sort order is compatible with doing
        that. (Robert Collins, Andrew Bennetts)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1461
1461
            a SearchResult from a smart server, in which case the keys list is
1462
1462
            not necessarily immediately available.
1463
1463
        """
1464
 
        self._recipe = (start_keys, exclude_keys, key_count)
 
1464
        self._recipe = ('search', start_keys, exclude_keys, key_count)
1465
1465
        self._keys = frozenset(keys)
1466
1466
 
1467
1467
    def get_recipe(self):
1474
1474
        added to the exclude list (or else ghost filling may alter the
1475
1475
        results).
1476
1476
 
1477
 
        :return: A tuple (start_keys_set, exclude_keys_set, revision_count). To
1478
 
            recreate the results of this search, create a breadth first
1479
 
            searcher on the same graph starting at start_keys. Then call next()
1480
 
            (or next_with_ghosts()) repeatedly, and on every result, call
1481
 
            stop_searching_any on any keys from the exclude_keys set. The
1482
 
            revision_count value acts as a trivial cross-check - the found
1483
 
            revisions of the new search should have as many elements as
 
1477
        :return: A tuple ('search', start_keys_set, exclude_keys_set,
 
1478
            revision_count). To recreate the results of this search, create a
 
1479
            breadth first searcher on the same graph starting at start_keys.
 
1480
            Then call next() (or next_with_ghosts()) repeatedly, and on every
 
1481
            result, call stop_searching_any on any keys from the exclude_keys
 
1482
            set. The revision_count value acts as a trivial cross-check - the
 
1483
            found revisions of the new search should have as many elements as
1484
1484
            revision_count. If it does not, then additional revisions have been
1485
1485
            ghosted since the search was executed the first time and the second
1486
1486
            time.
1494
1494
        """
1495
1495
        return self._keys
1496
1496
 
 
1497
    def is_empty(self):
 
1498
        """Return true if the search lists 1 or more revisions."""
 
1499
        return self._recipe[3] == 0
 
1500
 
 
1501
    def refine(self, seen, referenced):
 
1502
        """Create a new search by refining this search.
 
1503
 
 
1504
        :param seen: Revisions that have been satisfied.
 
1505
        :param referenced: Revision references observed while satisfying some
 
1506
            of this search.
 
1507
        """
 
1508
        start = self._recipe[1]
 
1509
        exclude = self._recipe[2]
 
1510
        count = self._recipe[3]
 
1511
        keys = self.get_keys()
 
1512
        # New heads = referenced + old heads - seen things - exclude
 
1513
        pending_refs = set(referenced)
 
1514
        pending_refs.update(start)
 
1515
        pending_refs.difference_update(seen)
 
1516
        pending_refs.difference_update(exclude)
 
1517
        # New exclude = old exclude + satisfied heads
 
1518
        seen_heads = start.intersection(seen)
 
1519
        exclude.update(seen_heads)
 
1520
        # keys gets seen removed
 
1521
        keys = keys - seen
 
1522
        # length is reduced by len(seen)
 
1523
        count -= len(seen)
 
1524
        return SearchResult(pending_refs, exclude, count, keys)
 
1525
 
1497
1526
 
1498
1527
class PendingAncestryResult(object):
1499
1528
    """A search result that will reconstruct the ancestry for some graph heads.
1509
1538
        :param repo: a repository to use to generate the ancestry for the given
1510
1539
            heads.
1511
1540
        """
1512
 
        self.heads = heads
 
1541
        self.heads = frozenset(heads)
1513
1542
        self.repo = repo
1514
1543
 
1515
1544
    def get_recipe(self):
1516
 
        raise NotImplementedError(self.get_recipe)
 
1545
        """Return a recipe that can be used to replay this search.
 
1546
 
 
1547
        The recipe allows reconstruction of the same results at a later date.
 
1548
 
 
1549
        :seealso SearchResult.get_recipe:
 
1550
 
 
1551
        :return: A tuple ('proxy-search', start_keys_set, set(), -1)
 
1552
            To recreate this result, create a PendingAncestryResult with the
 
1553
            start_keys_set.
 
1554
        """
 
1555
        return ('proxy-search', self.heads, set(), -1)
1517
1556
 
1518
1557
    def get_keys(self):
1519
1558
        """See SearchResult.get_keys.
1529
1568
                if key != NULL_REVISION]
1530
1569
        return keys
1531
1570
 
 
1571
    def is_empty(self):
 
1572
        """Return true if the search lists 1 or more revisions."""
 
1573
        if revision.NULL_REVISION in self.heads:
 
1574
            return len(self.heads) == 1
 
1575
        else:
 
1576
            return len(self.heads) == 0
 
1577
 
 
1578
    def refine(self, seen, referenced):
 
1579
        """Create a new search by refining this search.
 
1580
 
 
1581
        :param seen: Revisions that have been satisfied.
 
1582
        :param referenced: Revision references observed while satisfying some
 
1583
            of this search.
 
1584
        """
 
1585
        referenced = self.heads.union(referenced)
 
1586
        return PendingAncestryResult(referenced - seen, self.repo)
 
1587
 
1532
1588
 
1533
1589
def collapse_linear_regions(parent_map):
1534
1590
    """Collapse regions of the graph that are 'linear'.