/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 bzrlib/weave.py

  • Committer: John Arbash Meinel
  • Date: 2008-07-17 12:55:11 UTC
  • mfrom: (3556 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3557.
  • Revision ID: john@arbash-meinel.com-20080717125511-rjpil183ctky8l84
Merge bzr.dev 3556

Show diffs side-by-side

added added

removed removed

Lines of Context:
86
86
        WeaveRevisionNotPresent,
87
87
        )
88
88
import bzrlib.errors as errors
89
 
from bzrlib.osutils import sha_strings, split_lines
 
89
from bzrlib.osutils import dirname, sha_strings, split_lines
90
90
import bzrlib.patiencediff
 
91
from bzrlib.revision import NULL_REVISION
91
92
from bzrlib.symbol_versioning import *
92
93
from bzrlib.trace import mutter
93
94
from bzrlib.tsort import topo_sort
95
96
    AbsentContentFactory,
96
97
    adapter_registry,
97
98
    ContentFactory,
98
 
    InterVersionedFile,
99
99
    VersionedFile,
100
100
    )
101
101
from bzrlib.weavefile import _read_weave_v5, write_weave_v5
110
110
    def __init__(self, version, weave):
111
111
        """Create a WeaveContentFactory for version from weave."""
112
112
        ContentFactory.__init__(self)
113
 
        self.sha1 = weave.get_sha1s([version])[0]
 
113
        self.sha1 = weave.get_sha1s([version])[version]
114
114
        self.key = (version,)
115
115
        parents = weave.get_parent_map([version])[version]
116
116
        self.parents = tuple((parent,) for parent in parents)
119
119
 
120
120
    def get_bytes_as(self, storage_kind):
121
121
        if storage_kind == 'fulltext':
122
 
            return self._weave.get_text(self.key[0])
 
122
            return self._weave.get_text(self.key[-1])
123
123
        else:
124
124
            raise UnavailableRepresentation(self.key, storage_kind, 'fulltext')
125
125
 
214
214
    """
215
215
 
216
216
    __slots__ = ['_weave', '_parents', '_sha1s', '_names', '_name_map',
217
 
                 '_weave_name', '_matcher']
 
217
                 '_weave_name', '_matcher', '_allow_reserved']
218
218
    
219
 
    def __init__(self, weave_name=None, access_mode='w', matcher=None, get_scope=None):
 
219
    def __init__(self, weave_name=None, access_mode='w', matcher=None,
 
220
                 get_scope=None, allow_reserved=False):
220
221
        """Create a weave.
221
222
 
222
223
        :param get_scope: A callable that returns an opaque object to be used
239
240
        self._get_scope = get_scope
240
241
        self._scope = get_scope()
241
242
        self._access_mode = access_mode
 
243
        self._allow_reserved = allow_reserved
242
244
 
243
245
    def __repr__(self):
244
246
        return "Weave(%r)" % self._weave_name
278
280
 
279
281
    def _lookup(self, name):
280
282
        """Convert symbolic version name to index."""
281
 
        self.check_not_reserved_id(name)
 
283
        if not self._allow_reserved:
 
284
            self.check_not_reserved_id(name)
282
285
        try:
283
286
            return self._name_map[name]
284
287
        except KeyError:
307
310
        :return: An iterator of ContentFactory objects, each of which is only
308
311
            valid until the iterator is advanced.
309
312
        """
 
313
        versions = [version[-1] for version in versions]
310
314
        if ordering == 'topological':
311
315
            parents = self.get_parent_map(versions)
312
316
            new_versions = topo_sort(parents)
322
326
        """See VersionedFile.get_parent_map."""
323
327
        result = {}
324
328
        for version_id in version_ids:
325
 
            try:
326
 
                result[version_id] = tuple(
327
 
                    map(self._idx_to_name, self._parents[self._lookup(version_id)]))
328
 
            except RevisionNotPresent:
329
 
                pass
 
329
            if version_id == NULL_REVISION:
 
330
                parents = ()
 
331
            else:
 
332
                try:
 
333
                    parents = tuple(
 
334
                        map(self._idx_to_name,
 
335
                            self._parents[self._lookup(version_id)]))
 
336
                except RevisionNotPresent:
 
337
                    continue
 
338
            result[version_id] = parents
330
339
        return result
331
340
 
332
341
    def get_parents_with_ghosts(self, version_id):
647
656
                # not in either revision
648
657
                yield 'irrelevant', line
649
658
 
650
 
        yield 'unchanged', ''           # terminator
651
 
 
652
659
    def _extract(self, versions):
653
660
        """Yield annotation of lines in included set.
654
661
 
759
766
 
760
767
    def get_sha1s(self, version_ids):
761
768
        """See VersionedFile.get_sha1s()."""
762
 
        return [self._sha1s[self._lookup(v)] for v in version_ids]
 
769
        result = {}
 
770
        for v in version_ids:
 
771
            result[v] = self._sha1s[self._lookup(v)]
 
772
        return result
763
773
 
764
774
    def num_versions(self):
765
775
        """How many versions are in this weave?"""
834
844
        # no lines outside of insertion blocks, that deletions are
835
845
        # properly paired, etc.
836
846
 
837
 
    def _join(self, other, pb, msg, version_ids, ignore_missing):
838
 
        """Worker routine for join()."""
839
 
        if not other.versions():
840
 
            return          # nothing to update, easy
841
 
 
842
 
        if not version_ids:
843
 
            # versions is never none, InterWeave checks this.
844
 
            return 0
845
 
 
846
 
        # two loops so that we do not change ourselves before verifying it
847
 
        # will be ok
848
 
        # work through in index order to make sure we get all dependencies
849
 
        names_to_join = []
850
 
        processed = 0
851
 
        # get the selected versions only that are in other.versions.
852
 
        version_ids = set(other.versions()).intersection(set(version_ids))
853
 
        # pull in the referenced graph.
854
 
        version_ids = other.get_ancestry(version_ids)
855
 
        pending_parents = other.get_parent_map(version_ids)
856
 
        pending_graph = pending_parents.items()
857
 
        if len(pending_graph) != len(version_ids):
858
 
            raise RevisionNotPresent(
859
 
                set(version_ids) - set(pending_parents.keys()), self)
860
 
        for name in topo_sort(pending_graph):
861
 
            other_idx = other._name_map[name]
862
 
            # returns True if we have it, False if we need it.
863
 
            if not self._check_version_consistent(other, other_idx, name):
864
 
                names_to_join.append((other_idx, name))
865
 
            processed += 1
866
 
 
867
 
        if pb and not msg:
868
 
            msg = 'weave join'
869
 
 
870
 
        merged = 0
871
 
        time0 = time.time()
872
 
        for other_idx, name in names_to_join:
873
 
            # TODO: If all the parents of the other version are already
874
 
            # present then we can avoid some work by just taking the delta
875
 
            # and adjusting the offsets.
876
 
            new_parents = self._imported_parents(other, other_idx)
877
 
            sha1 = other._sha1s[other_idx]
878
 
 
879
 
            merged += 1
880
 
 
881
 
            if pb:
882
 
                pb.update(msg, merged, len(names_to_join))
883
 
           
884
 
            lines = other.get_lines(other_idx)
885
 
            self._add(name, lines, new_parents, sha1)
886
 
 
887
 
        mutter("merged = %d, processed = %d, file_id=%s; deltat=%d"%(
888
 
                merged, processed, self._weave_name, time.time()-time0))
889
 
 
890
847
    def _imported_parents(self, other, other_idx):
891
848
        """Return list of parents in self corresponding to indexes in other."""
892
849
        new_parents = []
954
911
        
955
912
        :param create: If not True, only open an existing knit.
956
913
        """
957
 
        super(WeaveFile, self).__init__(name, access_mode, get_scope=get_scope)
 
914
        super(WeaveFile, self).__init__(name, access_mode, get_scope=get_scope,
 
915
            allow_reserved=False)
958
916
        self._transport = transport
959
917
        self._filemode = filemode
960
918
        try:
989
947
        sio = StringIO()
990
948
        write_weave_v5(self, sio)
991
949
        sio.seek(0)
992
 
        self._transport.put_file(self._weave_name + WeaveFile.WEAVE_SUFFIX,
993
 
                                 sio,
994
 
                                 self._filemode)
 
950
        bytes = sio.getvalue()
 
951
        path = self._weave_name + WeaveFile.WEAVE_SUFFIX
 
952
        try:
 
953
            self._transport.put_bytes(path, bytes, self._filemode)
 
954
        except errors.NoSuchFile:
 
955
            self._transport.mkdir(dirname(path))
 
956
            self._transport.put_bytes(path, bytes, self._filemode)
995
957
 
996
958
    @staticmethod
997
959
    def get_suffixes():
1272
1234
if __name__ == '__main__':
1273
1235
    import sys
1274
1236
    sys.exit(main(sys.argv))
1275
 
 
1276
 
 
1277
 
class InterWeave(InterVersionedFile):
1278
 
    """Optimised code paths for weave to weave operations."""
1279
 
    
1280
 
    _matching_file_from_factory = staticmethod(WeaveFile)
1281
 
    _matching_file_to_factory = staticmethod(WeaveFile)
1282
 
    
1283
 
    @staticmethod
1284
 
    def is_compatible(source, target):
1285
 
        """Be compatible with weaves."""
1286
 
        try:
1287
 
            return (isinstance(source, Weave) and
1288
 
                    isinstance(target, Weave))
1289
 
        except AttributeError:
1290
 
            return False
1291
 
 
1292
 
    def join(self, pb=None, msg=None, version_ids=None, ignore_missing=False):
1293
 
        """See InterVersionedFile.join."""
1294
 
        version_ids = self._get_source_version_ids(version_ids, ignore_missing)
1295
 
        if self.target.versions() == [] and version_ids is None:
1296
 
            self.target._copy_weave_content(self.source)
1297
 
            return
1298
 
        self.target._join(self.source, pb, msg, version_ids, ignore_missing)
1299
 
 
1300
 
 
1301
 
InterVersionedFile.register_optimiser(InterWeave)