~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/versionedfile.py

Optimize common case where unique_lcs returns a set of lines all in a row

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2005 by Canonical Ltd
2
2
#
3
3
# Authors:
4
4
#   Johan Rydberg <jrydberg@gnu.org>
7
7
# it under the terms of the GNU General Public License as published by
8
8
# the Free Software Foundation; either version 2 of the License, or
9
9
# (at your option) any later version.
10
 
#
 
10
 
11
11
# This program is distributed in the hope that it will be useful,
12
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
14
# GNU General Public License for more details.
15
 
#
 
15
 
16
16
# You should have received a copy of the GNU General Public License
17
17
# along with this program; if not, write to the Free Software
18
18
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
19
 
20
20
"""Versioned text file storage api."""
21
21
 
22
 
from bzrlib.lazy_import import lazy_import
23
 
lazy_import(globals(), """
 
22
 
24
23
from copy import deepcopy
25
 
import unittest
26
 
 
27
 
from bzrlib import (
28
 
    errors,
29
 
    tsort,
30
 
    ui,
31
 
    )
32
 
from bzrlib.transport.memory import MemoryTransport
33
 
""")
34
 
 
 
24
from unittest import TestSuite
 
25
 
 
26
 
 
27
import bzrlib.errors as errors
35
28
from bzrlib.inter import InterObject
 
29
from bzrlib.symbol_versioning import *
36
30
from bzrlib.textmerge import TextMerge
37
 
from bzrlib.symbol_versioning import (deprecated_function,
38
 
        deprecated_method,
39
 
        zero_eight,
40
 
        )
 
31
from bzrlib.transport.memory import MemoryTransport
 
32
from bzrlib.tsort import topo_sort
 
33
from bzrlib import ui
41
34
 
42
35
 
43
36
class VersionedFile(object):
61
54
    def copy_to(self, name, transport):
62
55
        """Copy this versioned file to name on transport."""
63
56
        raise NotImplementedError(self.copy_to)
64
 
 
 
57
    
65
58
    @deprecated_method(zero_eight)
66
59
    def names(self):
67
60
        """Return a list of all the versions in this versioned file.
177
170
        if self._access_mode != 'w':
178
171
            raise errors.ReadOnlyObjectDirtiedError(self)
179
172
 
180
 
    def enable_cache(self):
181
 
        """Tell this versioned file that it should cache any data it reads.
182
 
        
183
 
        This is advisory, implementations do not have to support caching.
184
 
        """
185
 
        pass
186
 
    
187
173
    def clear_cache(self):
188
 
        """Remove any data cached in the versioned file object.
189
 
 
190
 
        This only needs to be supported if caches are supported
191
 
        """
192
 
        pass
 
174
        """Remove any data cached in the versioned file object."""
193
175
 
194
176
    def clone_text(self, new_version_id, old_version_id, parents):
195
177
        """Add an identical text to old_version_id as new_version_id.
270
252
        return ''.join(self.get_lines(version_id))
271
253
    get_string = get_text
272
254
 
273
 
    def get_texts(self, version_ids):
274
 
        """Return the texts of listed versions as a list of strings.
275
 
 
276
 
        Raises RevisionNotPresent if version is not present in
277
 
        file history.
278
 
        """
279
 
        return [''.join(self.get_lines(v)) for v in version_ids]
280
 
 
281
255
    def get_lines(self, version_id):
282
256
        """Return version contents as a sequence of lines.
283
257
 
313
287
        
314
288
        Ghosts are not listed or referenced in the graph.
315
289
        :param version_ids: Versions to select.
316
 
                            None means retrieve all versions.
 
290
                            None means retreive all versions.
317
291
        """
318
292
        result = {}
319
293
        if version_ids is None:
407
381
            version_ids,
408
382
            ignore_missing)
409
383
 
410
 
    def iter_lines_added_or_present_in_versions(self, version_ids=None, 
411
 
                                                pb=None):
 
384
    def iter_lines_added_or_present_in_versions(self, version_ids=None):
412
385
        """Iterate over the lines in the versioned file from version_ids.
413
386
 
414
387
        This may return lines from other versions, and does not return the
415
388
        specific version marker at this point. The api may be changed
416
389
        during development to include the version that the versioned file
417
390
        thinks is relevant, but given that such hints are just guesses,
418
 
        its better not to have it if we don't need it.
419
 
 
420
 
        If a progress bar is supplied, it may be used to indicate progress.
421
 
        The caller is responsible for cleaning up progress bars (because this
422
 
        is an iterator).
 
391
        its better not to have it if we dont need it.
423
392
 
424
393
        NOTES: Lines are normalised: they will all have \n terminators.
425
394
               Lines are returned in arbitrary order.
477
446
        """
478
447
        raise NotImplementedError(VersionedFile.plan_merge)
479
448
        
480
 
    def weave_merge(self, plan, a_marker=TextMerge.A_MARKER,
 
449
    def weave_merge(self, plan, a_marker=TextMerge.A_MARKER, 
481
450
                    b_marker=TextMerge.B_MARKER):
482
451
        return PlanWeaveMerge(plan, a_marker, b_marker).merge_lines()[0]
483
452
 
514
483
       
515
484
        # We previously considered either 'unchanged' or 'killed-both' lines
516
485
        # to be possible places to resynchronize.  However, assuming agreement
517
 
        # on killed-both lines may be too aggressive. -- mbp 20060324
 
486
        # on killed-both lines may be too agressive. -- mbp 20060324
518
487
        for state, line in self.plan:
519
488
            if state == 'unchanged':
520
489
                # resync and flush queued conflicts changes if any
567
536
    InterVersionedFile.get(other).method_name(parameters).
568
537
    """
569
538
 
570
 
    _optimisers = []
 
539
    _optimisers = set()
571
540
    """The available optimised InterVersionedFile types."""
572
541
 
573
542
    def join(self, pb=None, msg=None, version_ids=None, ignore_missing=False):
594
563
            target = temp_source
595
564
        version_ids = self._get_source_version_ids(version_ids, ignore_missing)
596
565
        graph = self.source.get_graph(version_ids)
597
 
        order = tsort.topo_sort(graph.items())
 
566
        order = topo_sort(graph.items())
598
567
        pb = ui.ui_factory.nested_progress_bar()
599
568
        parent_texts = {}
600
569
        try:
669
638
class InterVersionedFileTestProviderAdapter(object):
670
639
    """A tool to generate a suite testing multiple inter versioned-file classes.
671
640
 
672
 
    This is done by copying the test once for each InterVersionedFile provider
 
641
    This is done by copying the test once for each interversionedfile provider
673
642
    and injecting the transport_server, transport_readonly_server,
674
643
    versionedfile_factory and versionedfile_factory_to classes into each copy.
675
644
    Each copy is also given a new id() to make it easy to identify.
681
650
        self._formats = formats
682
651
    
683
652
    def adapt(self, test):
684
 
        result = unittest.TestSuite()
 
653
        result = TestSuite()
685
654
        for (interversionedfile_class,
686
655
             versionedfile_factory,
687
656
             versionedfile_factory_to) in self._formats: