~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to groupcompress.py

  • Committer: Ian Clatworthy
  • Date: 2009-03-02 06:35:43 UTC
  • mto: (0.23.30 groupcompress_rabin)
  • mto: This revision was merged to the branch mainline in revision 4280.
  • Revision ID: ian.clatworthy@canonical.com-20090302063543-czciz25uppelwhv0
groupcompress.py code cleanups

Show diffs side-by-side

added added

removed removed

Lines of Context:
57
57
    result = []
58
58
    lines = iter(line_list)
59
59
    next = lines.next
60
 
    label_line = lines.next()
61
 
    sha1_line = lines.next()
 
60
    label_line = next()
 
61
    sha1_line = next()
62
62
    if (not label_line.startswith('label: ') or
63
63
        not sha1_line.startswith('sha1: ')):
64
64
        raise AssertionError("bad text record %r" % lines)
111
111
    # gc-optimal ordering is approximately reverse topological,
112
112
    # properly grouped by file-id.
113
113
    per_prefix_map = {}
114
 
    present_keys = []
115
114
    for item in parent_map.iteritems():
116
115
        key = item[0]
117
116
        if isinstance(key, str) or len(key) == 1:
123
122
        except KeyError:
124
123
            per_prefix_map[prefix] = [item]
125
124
 
 
125
    present_keys = []
126
126
    for prefix in sorted(per_prefix_map):
127
127
        present_keys.extend(reversed(topo_sort(per_prefix_map[prefix])))
128
128
    return present_keys
149
149
    def __init__(self, delta=True):
150
150
        """Create a GroupCompressor.
151
151
 
152
 
        :paeam delta: If False, do not compress records.
 
152
        :param delta: If False, do not compress records.
153
153
        """
154
154
        self._delta = delta
155
155
        self.line_offsets = []
161
161
        self._present_prefixes = set()
162
162
 
163
163
    def get_matching_blocks(self, lines, soft=False):
164
 
        """Return an the ranges in lines which match self.lines.
 
164
        """Return the ranges in lines which match self.lines.
165
165
 
166
166
        :param lines: lines to compress
167
167
        :return: A list of (old_start, new_start, length) tuples which reflect
210
210
            e.g. sha1:xxxxxxx.
211
211
        :param lines: The lines to be compressed. Must be split
212
212
            on \n, with the \n preserved.'
213
 
        :param expected_sha: If non-None, the sha the lines are blieved to
 
213
        :param expected_sha: If non-None, the sha the lines are believed to
214
214
            have. During compression the sha is calculated; a mismatch will
215
215
            cause an error.
216
216
        :param soft: Do a 'soft' compression. This means that we require larger
240
240
        copy_ends = None
241
241
        blocks = self.get_matching_blocks(lines, soft=soft)
242
242
        current_pos = 0
243
 
        copies_without_insertion = []
 
243
        #copies_without_insertion = []
244
244
        # We either copy a range (while there are reusable lines) or we
245
245
        # insert new lines. To find reusable lines we traverse
246
246
        for old_start, new_start, range_len in blocks:
365
365
        parents = graph or delta
366
366
        ref_length = 0
367
367
        if graph:
368
 
            ref_length += 1
 
368
            ref_length = 1
369
369
        graph_index = BTreeBuilder(reference_lists=ref_length,
370
370
            key_elements=keylength)
371
371
        stream = transport.open_write_stream('newpack')
625
625
            present_keys = sorted(locations.iterkeys(), key=get_group)
626
626
            # We don't have an ordering for keys in the in-memory object, but
627
627
            # lets process the in-memory ones first.
628
 
            local = list(local_keys)
629
628
            present_keys = list(local_keys) + present_keys
630
629
        absent_keys = keys.difference(set(locations))
631
630
        for key in absent_keys:
637
636
            else:
638
637
                index_memo, _, parents, (method, _) = locations[key]
639
638
                plain, delta_lines = self._get_group_and_delta_lines(index_memo)
640
 
                ## delta = parse(delta_lines)
641
639
                label, sha1, delta = parse(delta_lines)
642
640
                if label != key:
643
641
                    raise AssertionError("wrong key: %r, wanted %r" % (label, key))
644
642
                chunks = apply_delta(plain, delta)
645
 
                ## sha1 = sha_strings(lines)
646
643
                if sha_strings(chunks) != sha1:
647
644
                    raise AssertionError('sha1 sum did not match')
648
645
            yield ChunkedContentFactory(key, parents, sha1, chunks)
680
677
        :seealso insert_record_stream:
681
678
        :seealso add_lines:
682
679
        """
 
680
        adapters = {}
683
681
        def get_adapter(adapter_key):
684
682
            try:
685
683
                return adapters[adapter_key]
688
686
                adapter = adapter_factory(self)
689
687
                adapters[adapter_key] = adapter
690
688
                return adapter
691
 
        adapters = {}
692
689
        # This will go up to fulltexts for gc to gc fetching, which isn't
693
690
        # ideal.
694
691
        self._compressor = GroupCompressor(self._delta)
708
705
        for record in stream:
709
706
            # Raise an error when a record is missing.
710
707
            if record.storage_kind == 'absent':
711
 
                raise errors.RevisionNotPresent([record.key], self)
 
708
                raise errors.RevisionNotPresent(record.key, self)
712
709
            try:
713
710
                lines = osutils.chunks_to_lines(record.get_bytes_as('chunked'))
714
711
            except errors.UnavailableRepresentation:
784
781
            'unordered', True)):
785
782
            # XXX: todo - optimise to use less than full texts.
786
783
            key = record.key
787
 
            pb.update('Walking content.', key_idx, total)
 
784
            pb.update('Walking content.', key_idx + 1, total)
788
785
            if record.storage_kind == 'absent':
789
 
                raise errors.RevisionNotPresent(record.key, self)
 
786
                raise errors.RevisionNotPresent(key, self)
790
787
            lines = split_lines(record.get_bytes_as('fulltext'))
791
788
            for line in lines:
792
789
                yield line, key
811
808
        """Construct a _GCGraphIndex on a graph_index.
812
809
 
813
810
        :param graph_index: An implementation of bzrlib.index.GraphIndex.
814
 
        :param is_locked: A callback to check whether the object should answer
815
 
            queries.
 
811
        :param is_locked: A callback, returns True if the index is locked and
 
812
            thus usable.
816
813
        :param parents: If True, record knits parents, if not do not record 
817
814
            parents.
818
815
        :param add_callback: If not None, allow additions to the index and call
819
816
            this callback with a list of added GraphIndex nodes:
820
817
            [(node, value, node_refs), ...]
821
 
        :param is_locked: A callback, returns True if the index is locked and
822
 
            thus usable.
823
818
        """
824
819
        self._add_callback = add_callback
825
820
        self._graph_index = graph_index
879
874
        self._add_callback(records)
880
875
        
881
876
    def _check_read(self):
882
 
        """raise if reads are not permitted."""
 
877
        """Raise an exception if reads are not permitted."""
883
878
        if not self._is_locked():
884
879
            raise errors.ObjectNotLocked(self)
885
880
 
886
881
    def _check_write_ok(self):
887
 
        """Assert if writes are not permitted."""
 
882
        """Raise an exception if writes are not permitted."""
888
883
        if not self._is_locked():
889
884
            raise errors.ObjectNotLocked(self)
890
885
 
891
886
    def _get_entries(self, keys, check_present=False):
892
887
        """Get the entries for keys.
893
 
        
 
888
 
 
889
        Note: Callers are responsible for checking that the index is locked
 
890
        before calling this method.
 
891
 
894
892
        :param keys: An iterable of index key tuples.
895
893
        """
896
894
        keys = set(keys)
948
946
        """
949
947
        self._check_read()
950
948
        result = {}
951
 
        entries = self._get_entries(keys, False)
 
949
        entries = self._get_entries(keys)
952
950
        for entry in entries:
953
951
            key = entry[1]
954
952
            if not self._parents:
955
953
                parents = None
956
954
            else:
957
955
                parents = entry[3][0]
958
 
            value = entry[2]
959
956
            method = 'group'
960
957
            result[key] = (self._node_to_position(entry),
961
958
                                  None, parents, (method, None))