~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/versionedfile.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-09-06 03:41:24 UTC
  • mfrom: (2794.1.3 knits)
  • Revision ID: pqm@pqm.ubuntu.com-20070906034124-gf4re7orinpud4to
(robertc) Nuke VersionedFile add/get delta support which was never used, and reduce memory copies during commits of unannotated file such as inventory. (Robert Collins).

Show diffs side-by-side

added added

removed removed

Lines of Context:
77
77
        """Returns whether version is present."""
78
78
        raise NotImplementedError(self.has_version)
79
79
 
80
 
    def add_delta(self, version_id, parents, delta_parent, sha1, noeol, delta):
81
 
        """Add a text to the versioned file via a pregenerated delta.
82
 
 
83
 
        :param version_id: The version id being added.
84
 
        :param parents: The parents of the version_id.
85
 
        :param delta_parent: The parent this delta was created against.
86
 
        :param sha1: The sha1 of the full text.
87
 
        :param delta: The delta instructions. See get_delta for details.
88
 
        """
89
 
        version_id = osutils.safe_revision_id(version_id)
90
 
        parents = [osutils.safe_revision_id(v) for v in parents]
91
 
        self._check_write_ok()
92
 
        if self.has_version(version_id):
93
 
            raise errors.RevisionAlreadyPresent(version_id, self)
94
 
        return self._add_delta(version_id, parents, delta_parent, sha1, noeol, delta)
95
 
 
96
 
    def _add_delta(self, version_id, parents, delta_parent, sha1, noeol, delta):
97
 
        """Class specific routine to add a delta.
98
 
 
99
 
        This generic version simply applies the delta to the delta_parent and
100
 
        then inserts it.
101
 
        """
102
 
        # strip annotation from delta
103
 
        new_delta = []
104
 
        for start, stop, delta_len, delta_lines in delta:
105
 
            new_delta.append((start, stop, delta_len, [text for origin, text in delta_lines]))
106
 
        if delta_parent is not None:
107
 
            parent_full = self.get_lines(delta_parent)
108
 
        else:
109
 
            parent_full = []
110
 
        new_full = self._apply_delta(parent_full, new_delta)
111
 
        # its impossible to have noeol on an empty file
112
 
        if noeol and new_full[-1][-1] == '\n':
113
 
            new_full[-1] = new_full[-1][:-1]
114
 
        self.add_lines(version_id, parents, new_full)
115
 
 
116
80
    def add_lines(self, version_id, parents, lines, parent_texts=None,
117
 
                  left_matching_blocks=None):
 
81
                  left_matching_blocks=None, nostore_sha=None):
118
82
        """Add a single text on top of the versioned file.
119
83
 
120
84
        Must raise RevisionAlreadyPresent if the new version is
130
94
        :param left_matching_blocks: a hint about which areas are common
131
95
            between the text and its left-hand-parent.  The format is
132
96
            the SequenceMatcher.get_matching_blocks format.
 
97
        :param nostore_sha: Raise ExistingContent and do not add the lines to
 
98
            the versioned file if the digest of the lines matches this.
133
99
        :return: The text sha1, the number of bytes in the text, and an opaque
134
100
                 representation of the inserted version which can be provided
135
101
                 back to future add_lines calls in the parent_texts dictionary.
138
104
        parents = [osutils.safe_revision_id(v) for v in parents]
139
105
        self._check_write_ok()
140
106
        return self._add_lines(version_id, parents, lines, parent_texts,
141
 
                               left_matching_blocks)
 
107
            left_matching_blocks, nostore_sha)
142
108
 
143
109
    def _add_lines(self, version_id, parents, lines, parent_texts,
144
 
                   left_matching_blocks):
 
110
        left_matching_blocks, nostore_sha):
145
111
        """Helper to do the class specific add_lines."""
146
112
        raise NotImplementedError(self.add_lines)
147
113
 
148
114
    def add_lines_with_ghosts(self, version_id, parents, lines,
149
 
                              parent_texts=None):
 
115
                              parent_texts=None, nostore_sha=None):
150
116
        """Add lines to the versioned file, allowing ghosts to be present.
151
117
        
152
 
        This takes the same parameters as add_lines.
 
118
        This takes the same parameters as add_lines and returns the same.
153
119
        """
154
120
        version_id = osutils.safe_revision_id(version_id)
155
121
        parents = [osutils.safe_revision_id(v) for v in parents]
156
122
        self._check_write_ok()
157
123
        return self._add_lines_with_ghosts(version_id, parents, lines,
158
 
                                           parent_texts)
 
124
            parent_texts, nostore_sha)
159
125
 
160
 
    def _add_lines_with_ghosts(self, version_id, parents, lines, parent_texts):
 
126
    def _add_lines_with_ghosts(self, version_id, parents, lines, parent_texts,
 
127
        nostore_sha):
161
128
        """Helper to do class specific add_lines_with_ghosts."""
162
129
        raise NotImplementedError(self.add_lines_with_ghosts)
163
130
 
241
208
        """Helper for fix_parents."""
242
209
        raise NotImplementedError(self.fix_parents)
243
210
 
244
 
    def get_delta(self, version):
245
 
        """Get a delta for constructing version from some other version.
246
 
        
247
 
        :return: (delta_parent, sha1, noeol, delta)
248
 
        Where delta_parent is a version id or None to indicate no parent.
249
 
        """
250
 
        raise NotImplementedError(self.get_delta)
251
 
 
252
 
    def get_deltas(self, version_ids):
253
 
        """Get multiple deltas at once for constructing versions.
254
 
        
255
 
        :return: dict(version_id:(delta_parent, sha1, noeol, delta))
256
 
        Where delta_parent is a version id or None to indicate no parent, and
257
 
        version_id is the version_id created by that delta.
258
 
        """
259
 
        result = {}
260
 
        for version_id in version_ids:
261
 
            result[version_id] = self.get_delta(version_id)
262
 
        return result
263
 
 
264
211
    def get_format_signature(self):
265
212
        """Get a text description of the data encoding in this file.
266
213
        
684
631
            # TODO: remove parent texts when they are not relevant any more for 
685
632
            # memory pressure reduction. RBC 20060313
686
633
            # pb.update('Converting versioned data', 0, len(order))
687
 
            # deltas = self.source.get_deltas(order)
688
634
            for index, version in enumerate(order):
689
635
                pb.update('Converting versioned data', index, len(order))
690
636
                _, _, parent_text = target.add_lines(version,
692
638
                                               self.source.get_lines(version),
693
639
                                               parent_texts=parent_texts)
694
640
                parent_texts[version] = parent_text
695
 
                #delta_parent, sha1, noeol, delta = deltas[version]
696
 
                #target.add_delta(version,
697
 
                #                 self.source.get_parents(version),
698
 
                #                 delta_parent,
699
 
                #                 sha1,
700
 
                #                 noeol,
701
 
                #                 delta)
702
 
                #target.get_lines(version)
703
641
            
704
642
            # this should hit the native code path for target
705
643
            if target is not self.target: