/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/index.py

  • Committer: Jelmer Vernooij
  • Date: 2017-06-05 23:35:09 UTC
  • mfrom: (6658 work)
  • mto: (6653.3.3 bzrwt)
  • mto: This revision was merged to the branch mainline in revision 6667.
  • Revision ID: jelmer@jelmer.uk-20170605233509-30wo916k6meuggqf
MergeĀ lp:brz

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
    )
45
45
from .sixish import (
46
46
    BytesIO,
 
47
    viewvalues,
 
48
    viewitems,
47
49
    )
48
50
from .static_tuple import StaticTuple
49
51
 
143
145
        if self._nodes_by_key is None:
144
146
            nodes_by_key = {}
145
147
            if self.reference_lists:
146
 
                for key, (absent, references, value) in self._nodes.iteritems():
 
148
                for key, (absent, references, value) in viewitems(self._nodes):
147
149
                    if absent:
148
150
                        continue
149
151
                    key_dict = nodes_by_key
151
153
                        key_dict = key_dict.setdefault(subkey, {})
152
154
                    key_dict[key[-1]] = key, value, references
153
155
            else:
154
 
                for key, (absent, references, value) in self._nodes.iteritems():
 
156
                for key, (absent, references, value) in viewitems(self._nodes):
155
157
                    if absent:
156
158
                        continue
157
159
                    key_dict = nodes_by_key
275
277
        # forward sorted by key. In future we may consider topological sorting,
276
278
        # at the cost of table scans for direct lookup, or a second index for
277
279
        # direct lookup
278
 
        nodes = sorted(self._nodes.items())
 
280
        nodes = sorted(viewitems(self._nodes))
279
281
        # if we do not prepass, we don't know how long it will be up front.
280
282
        expected_bytes = None
281
283
        # we only need to pre-pass if we have reference lists at all.
478
480
        stream.close()
479
481
        del lines[-1]
480
482
        _, _, _, trailers = self._parse_lines(lines, pos)
481
 
        for key, absent, references, value in self._keys_by_offset.itervalues():
 
483
        for key, absent, references, value in viewvalues(self._keys_by_offset):
482
484
            if absent:
483
485
                continue
484
486
            # resolve references:
509
511
                % (ref_list_num, self.node_ref_lists))
510
512
        refs = set()
511
513
        nodes = self._nodes
512
 
        for key, (value, ref_lists) in nodes.iteritems():
 
514
        for key, (value, ref_lists) in viewitems(nodes):
513
515
            ref_list = ref_lists[ref_list_num]
514
516
            refs.update([ref for ref in ref_list if ref not in nodes])
515
517
        return refs
518
520
        if self._nodes_by_key is None:
519
521
            nodes_by_key = {}
520
522
            if self.node_ref_lists:
521
 
                for key, (value, references) in self._nodes.iteritems():
 
523
                for key, (value, references) in viewitems(self._nodes):
522
524
                    key_dict = nodes_by_key
523
525
                    for subkey in key[:-1]:
524
526
                        key_dict = key_dict.setdefault(subkey, {})
525
527
                    key_dict[key[-1]] = key, value, references
526
528
            else:
527
 
                for key, value in self._nodes.iteritems():
 
529
                for key, value in viewitems(self._nodes):
528
530
                    key_dict = nodes_by_key
529
531
                    for subkey in key[:-1]:
530
532
                        key_dict = key_dict.setdefault(subkey, {})
547
549
        if self._nodes is None:
548
550
            self._buffer_all()
549
551
        if self.node_ref_lists:
550
 
            for key, (value, node_ref_lists) in self._nodes.iteritems():
 
552
            for key, (value, node_ref_lists) in viewitems(self._nodes):
551
553
                yield self, key, value, node_ref_lists
552
554
        else:
553
 
            for key, value in self._nodes.iteritems():
 
555
            for key, value in viewitems(self._nodes):
554
556
                yield self, key, value
555
557
 
556
558
    def _read_prefix(self, stream):
716
718
            self._buffer_all()
717
719
        if self._key_length == 1:
718
720
            for key in keys:
719
 
                # sanity check
720
 
                if key[0] is None:
721
 
                    raise errors.BadIndexKey(key)
722
 
                if len(key) != self._key_length:
723
 
                    raise errors.BadIndexKey(key)
 
721
                _sanity_check_key(self, key)
724
722
                if self.node_ref_lists:
725
723
                    value, node_refs = self._nodes[key]
726
724
                    yield self, key, value, node_refs
728
726
                    yield self, key, self._nodes[key]
729
727
            return
730
728
        nodes_by_key = self._get_nodes_by_key()
731
 
        for key in keys:
732
 
            # sanity check
733
 
            if key[0] is None:
734
 
                raise errors.BadIndexKey(key)
735
 
            if len(key) != self._key_length:
736
 
                raise errors.BadIndexKey(key)
737
 
            # find what it refers to:
738
 
            key_dict = nodes_by_key
739
 
            elements = list(key)
740
 
            # find the subdict whose contents should be returned.
741
 
            try:
742
 
                while len(elements) and elements[0] is not None:
743
 
                    key_dict = key_dict[elements[0]]
744
 
                    elements.pop(0)
745
 
            except KeyError:
746
 
                # a non-existant lookup.
747
 
                continue
748
 
            if len(elements):
749
 
                dicts = [key_dict]
750
 
                while dicts:
751
 
                    key_dict = dicts.pop(-1)
752
 
                    # can't be empty or would not exist
753
 
                    item, value = next(key_dict.iteritems())
754
 
                    if isinstance(value, dict):
755
 
                        # push keys
756
 
                        dicts.extend(key_dict.itervalues())
757
 
                    else:
758
 
                        # yield keys
759
 
                        for value in key_dict.itervalues():
760
 
                            # each value is the key:value:node refs tuple
761
 
                            # ready to yield.
762
 
                            yield (self, ) + value
763
 
            else:
764
 
                # the last thing looked up was a terminal element
765
 
                yield (self, ) + key_dict
 
729
        for entry in _iter_entries_prefix(self, nodes_by_key, keys):
 
730
            yield entry
766
731
 
767
732
    def _find_ancestors(self, keys, ref_list_num, parent_map, missing_keys):
768
733
        """See BTreeIndex._find_ancestors."""
1635
1600
            trace.mutter_callsite(3,
1636
1601
                "iter_all_entries scales with size of history.")
1637
1602
        if self.reference_lists:
1638
 
            for key, (absent, references, value) in self._nodes.iteritems():
 
1603
            for key, (absent, references, value) in viewitems(self._nodes):
1639
1604
                if not absent:
1640
1605
                    yield self, key, value, references
1641
1606
        else:
1642
 
            for key, (absent, references, value) in self._nodes.iteritems():
 
1607
            for key, (absent, references, value) in viewitems(self._nodes):
1643
1608
                if not absent:
1644
1609
                    yield self, key, value
1645
1610
 
1683
1648
            will be returned, and every match that is in the index will be
1684
1649
            returned.
1685
1650
        """
1686
 
        # XXX: To much duplication with the GraphIndex class; consider finding
1687
 
        # a good place to pull out the actual common logic.
1688
1651
        keys = set(keys)
1689
1652
        if not keys:
1690
1653
            return
1691
1654
        if self._key_length == 1:
1692
1655
            for key in keys:
1693
 
                # sanity check
1694
 
                if key[0] is None:
1695
 
                    raise errors.BadIndexKey(key)
1696
 
                if len(key) != self._key_length:
1697
 
                    raise errors.BadIndexKey(key)
 
1656
                _sanity_check_key(self, key)
1698
1657
                node = self._nodes[key]
1699
1658
                if node[0]:
1700
1659
                    continue
1704
1663
                    yield self, key, node[2]
1705
1664
            return
1706
1665
        nodes_by_key = self._get_nodes_by_key()
1707
 
        for key in keys:
1708
 
            # sanity check
1709
 
            if key[0] is None:
1710
 
                raise errors.BadIndexKey(key)
1711
 
            if len(key) != self._key_length:
1712
 
                raise errors.BadIndexKey(key)
1713
 
            # find what it refers to:
1714
 
            key_dict = nodes_by_key
1715
 
            elements = list(key)
1716
 
            # find the subdict to return
1717
 
            try:
1718
 
                while len(elements) and elements[0] is not None:
1719
 
                    key_dict = key_dict[elements[0]]
1720
 
                    elements.pop(0)
1721
 
            except KeyError:
1722
 
                # a non-existant lookup.
1723
 
                continue
1724
 
            if len(elements):
1725
 
                dicts = [key_dict]
1726
 
                while dicts:
1727
 
                    key_dict = dicts.pop(-1)
1728
 
                    # can't be empty or would not exist
1729
 
                    item, value = next(key_dict.iteritems())
1730
 
                    if isinstance(value, dict):
1731
 
                        # push keys
1732
 
                        dicts.extend(key_dict.itervalues())
1733
 
                    else:
1734
 
                        # yield keys
1735
 
                        for value in key_dict.itervalues():
1736
 
                            yield (self, ) + value
1737
 
            else:
1738
 
                yield (self, ) + key_dict
 
1666
        for entry in _iter_entries_prefix(self, nodes_by_key, keys):
 
1667
            yield entry
1739
1668
 
1740
1669
    def key_count(self):
1741
1670
        """Return an estimate of the number of keys in this index.
1873
1802
    def validate(self):
1874
1803
        """Call the adapted's validate."""
1875
1804
        self.adapted.validate()
 
1805
 
 
1806
 
 
1807
def _sanity_check_key(index_or_builder, key):
 
1808
    """Raise BadIndexKey if key cannot be used for prefix matching."""
 
1809
    if key[0] is None:
 
1810
        raise errors.BadIndexKey(key)
 
1811
    if len(key) != index_or_builder._key_length:
 
1812
        raise errors.BadIndexKey(key)
 
1813
 
 
1814
 
 
1815
def _iter_entries_prefix(index_or_builder, nodes_by_key, keys):
 
1816
    """Helper for implementing prefix matching iterators."""
 
1817
    for key in keys:
 
1818
        _sanity_check_key(index_or_builder, key)
 
1819
        # find what it refers to:
 
1820
        key_dict = nodes_by_key
 
1821
        elements = list(key)
 
1822
        # find the subdict whose contents should be returned.
 
1823
        try:
 
1824
            while len(elements) and elements[0] is not None:
 
1825
                key_dict = key_dict[elements[0]]
 
1826
                elements.pop(0)
 
1827
        except KeyError:
 
1828
            # a non-existant lookup.
 
1829
            continue
 
1830
        if len(elements):
 
1831
            dicts = [key_dict]
 
1832
            while dicts:
 
1833
                values_view = viewvalues(dicts.pop())
 
1834
                # can't be empty or would not exist
 
1835
                value = next(iter(values_view))
 
1836
                if isinstance(value, dict):
 
1837
                    # still descending, push values
 
1838
                    dicts.extend(values_view)
 
1839
                else:
 
1840
                    # at leaf tuples, yield values
 
1841
                    for value in values_view:
 
1842
                        # each value is the key:value:node refs tuple
 
1843
                        # ready to yield.
 
1844
                        yield (index_or_builder, ) + value
 
1845
        else:
 
1846
            # the last thing looked up was a terminal element
 
1847
            yield (index_or_builder, ) + key_dict