~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: 2006-03-09 06:39:13 UTC
  • mfrom: (1596.2.6 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20060309063913-6d8ce700706d0802
Merge knit performance stage 1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
from unittest import TestSuite
29
29
 
30
30
 
 
31
import bzrlib.errors as errors
31
32
from bzrlib.inter import InterObject
32
33
from bzrlib.symbol_versioning import *
33
34
from bzrlib.transport.memory import MemoryTransport
49
50
    Texts are identified by a version-id string.
50
51
    """
51
52
 
 
53
    def __init__(self, access_mode):
 
54
        self.finished = False
 
55
        self._access_mode = access_mode
 
56
 
52
57
    def copy_to(self, name, transport):
53
58
        """Copy this versioned file to name on transport."""
54
59
        raise NotImplementedError(self.copy_to)
65
70
        """Return a unsorted list of versions."""
66
71
        raise NotImplementedError(self.versions)
67
72
 
 
73
    def has_ghost(self, version_id):
 
74
        """Returns whether version is present as a ghost."""
 
75
        raise NotImplementedError(self.has_ghost)
 
76
 
68
77
    def has_version(self, version_id):
69
78
        """Returns whether version is present."""
70
79
        raise NotImplementedError(self.has_version)
76
85
        already present in file history.
77
86
 
78
87
        Must raise RevisionNotPresent if any of the given parents are
79
 
        not present in file history."""
 
88
        not present in file history.
 
89
        """
 
90
        self._check_write_ok()
 
91
        return self._add_lines(version_id, parents, lines)
 
92
 
 
93
    def _add_lines(self, version_id, parents, lines):
 
94
        """Helper to do the class specific add_lines."""
80
95
        raise NotImplementedError(self.add_lines)
81
96
 
 
97
    def add_lines_with_ghosts(self, version_id, parents, lines):
 
98
        """Add lines to the versioned file, allowing ghosts to be present."""
 
99
        self._check_write_ok()
 
100
        return self._add_lines_with_ghosts(version_id, parents, lines)
 
101
 
 
102
    def _add_lines_with_ghosts(self, version_id, parents, lines):
 
103
        """Helper to do class specific add_lines_with_ghosts."""
 
104
        raise NotImplementedError(self.add_lines_with_ghosts)
 
105
 
82
106
    def check(self, progress_bar=None):
83
107
        """Check the versioned file for integrity."""
84
108
        raise NotImplementedError(self.check)
85
109
 
 
110
    def _check_write_ok(self):
 
111
        """Is the versioned file marked as 'finished' ? Raise if it is."""
 
112
        if self.finished:
 
113
            raise errors.OutSideTransaction()
 
114
        if self._access_mode != 'w':
 
115
            raise errors.ReadOnlyObjectDirtiedError(self)
 
116
 
86
117
    def clear_cache(self):
87
118
        """Remove any data cached in the versioned file object."""
88
119
 
94
125
 
95
126
        Must raise RevisionAlreadyPresent if the new version is
96
127
        already present in file history."""
 
128
        self._check_write_ok()
 
129
        return self._clone_text(new_version_id, old_version_id, parents)
 
130
 
 
131
    def _clone_text(self, new_version_id, old_version_id, parents):
 
132
        """Helper function to do the _clone_text work."""
97
133
        raise NotImplementedError(self.clone_text)
98
134
 
99
135
    def create_empty(self, name, transport, mode=None):
105
141
        """
106
142
        raise NotImplementedError(self.create_empty)
107
143
 
 
144
    def fix_parents(self, version, new_parents):
 
145
        """Fix the parents list for version.
 
146
        
 
147
        This is done by appending a new version to the index
 
148
        with identical data except for the parents list.
 
149
        the parents list must be a superset of the current
 
150
        list.
 
151
        """
 
152
        self._check_write_ok()
 
153
        return self._fix_parents(version, new_parents)
 
154
 
 
155
    def _fix_parents(self, version, new_parents):
 
156
        """Helper for fix_parents."""
 
157
        raise NotImplementedError(self.fix_parents)
 
158
 
108
159
    def get_suffixes(self):
109
160
        """Return the file suffixes associated with this versioned file."""
110
161
        raise NotImplementedError(self.get_suffixes)
136
187
            version_ids = [version_ids]
137
188
        raise NotImplementedError(self.get_ancestry)
138
189
        
 
190
    def get_ancestry_with_ghosts(self, version_ids):
 
191
        """Return a list of all ancestors of given version(s). This
 
192
        will not include the null revision.
 
193
 
 
194
        Must raise RevisionNotPresent if any of the given versions are
 
195
        not present in file history.
 
196
        
 
197
        Ghosts that are known about will be included in ancestry list,
 
198
        but are not explicitly marked.
 
199
        """
 
200
        raise NotImplementedError(self.get_ancestry_with_ghosts)
 
201
        
139
202
    def get_graph(self):
140
 
        """Return a graph for the entire versioned file."""
 
203
        """Return a graph for the entire versioned file.
 
204
        
 
205
        Ghosts are not listed or referenced in the graph.
 
206
        """
141
207
        result = {}
142
208
        for version in self.versions():
143
209
            result[version] = self.get_parents(version)
144
210
        return result
145
211
 
 
212
    def get_graph_with_ghosts(self):
 
213
        """Return a graph for the entire versioned file.
 
214
        
 
215
        Ghosts are referenced in parents list but are not
 
216
        explicitly listed.
 
217
        """
 
218
        raise NotImplementedError(self.get_graph_with_ghosts)
 
219
 
146
220
    @deprecated_method(zero_eight)
147
221
    def parent_names(self, version):
148
222
        """Return version names for parents of a version.
159
233
        """
160
234
        raise NotImplementedError(self.get_parents)
161
235
 
 
236
    def get_parents_with_ghosts(self, version_id):
 
237
        """Return version names for parents of version_id.
 
238
 
 
239
        Will raise RevisionNotPresent if version_id is not present
 
240
        in the history.
 
241
 
 
242
        Ghosts that are known about will be included in the parent list,
 
243
        but are not explicitly marked.
 
244
        """
 
245
        raise NotImplementedError(self.get_parents_with_ghosts)
 
246
 
162
247
    def annotate_iter(self, version_id):
163
248
        """Yield list of (version-id, line) pairs for the specified
164
249
        version.
182
267
        are not present in the other files history unless ignore_missing
183
268
        is supplied when they are silently skipped.
184
269
        """
 
270
        self._check_write_ok()
185
271
        return InterVersionedFile.get(other, self).join(
186
272
            pb,
187
273
            msg,
188
274
            version_ids,
189
275
            ignore_missing)
190
276
 
 
277
    def iter_lines_added_or_present_in_versions(self, version_ids=None):
 
278
        """Iterate over the lines in the versioned file from version_ids.
 
279
 
 
280
        This may return lines from other versions, and does not return the
 
281
        specific version marker at this point. The api may be changed
 
282
        during development to include the version that the versioned file
 
283
        thinks is relevant, but given that such hints are just guesses,
 
284
        its better not to have it if we dont need it.
 
285
 
 
286
        NOTES: Lines are normalised: they will all have \n terminators.
 
287
               Lines are returned in arbitrary order.
 
288
        """
 
289
        raise NotImplementedError(self.iter_lines_added_or_present_in_versions)
 
290
 
 
291
    def transaction_finished(self):
 
292
        """The transaction that this file was opened in has finished.
 
293
 
 
294
        This records self.finished = True and should cause all mutating
 
295
        operations to error.
 
296
        """
 
297
        self.finished = True
 
298
 
 
299
    @deprecated_method(zero_eight)
191
300
    def walk(self, version_ids=None):
192
301
        """Walk the versioned file as a weave-like structure, for
193
302
        versions relative to version_ids.  Yields sequence of (lineno,
198
307
 
199
308
        :param version_ids: the version_ids to walk with respect to. If not
200
309
                            supplied the entire weave-like structure is walked.
 
310
 
 
311
        walk is deprecated in favour of iter_lines_added_or_present_in_versions
201
312
        """
202
313
        raise NotImplementedError(self.walk)
203
314
 
218
329
        inc_b = set(self.get_ancestry([ver_b]))
219
330
        inc_c = inc_a & inc_b
220
331
 
221
 
        for lineno, insert, deleteset, line in self.walk():
 
332
        for lineno, insert, deleteset, line in self.walk([ver_a, ver_b]):
222
333
            if deleteset & inc_c:
223
334
                # killed in parent; can't be in either a or b
224
335
                # not relevant to our work
331
442
        supplied when they are silently skipped.
332
443
        """
333
444
        # the default join: 
 
445
        # - if the target is empty, just add all the versions from 
 
446
        #   source to target, otherwise:
334
447
        # - make a temporary versioned file of type target
335
448
        # - insert the source content into it one at a time
336
449
        # - join them
337
 
        # Make a new target-format versioned file. 
338
 
        temp_source = self.target.create_empty("temp", MemoryTransport())
 
450
        if not self.target.versions():
 
451
            target = self.target
 
452
        else:
 
453
            # Make a new target-format versioned file. 
 
454
            temp_source = self.target.create_empty("temp", MemoryTransport())
 
455
            target = temp_source
339
456
        graph = self.source.get_graph()
340
457
        order = topo_sort(graph.items())
341
458
        pb = ui.ui_factory.nested_progress_bar()
342
459
        try:
343
460
            for index, version in enumerate(order):
344
461
                pb.update('Converting versioned data', index, len(order))
345
 
                temp_source.add_lines(version,
346
 
                                      self.source.get_parents(version),
347
 
                                      self.source.get_lines(version))
 
462
                target.add_lines(version,
 
463
                                 self.source.get_parents(version),
 
464
                                 self.source.get_lines(version))
348
465
            
349
466
            # this should hit the native code path for target
350
 
            return self.target.join(temp_source,
351
 
                                    pb,
352
 
                                    msg,
353
 
                                    version_ids,
354
 
                                    ignore_missing)
 
467
            if target is not self.target:
 
468
                return self.target.join(temp_source,
 
469
                                        pb,
 
470
                                        msg,
 
471
                                        version_ids,
 
472
                                        ignore_missing)
355
473
        finally:
356
474
            pb.finished()
357
475