~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/fetch.py

[patch] weave fetch optimizations (Goffredo Baroncelli)

The patch adds 2 optimizations:

1) The patch add a hash ( file_ids_names ) which caches the revision
contained in a weave already  processed, so it isn't needed to reload the
weave in order to check if a revision is present.

2) Moreover if it is required to merge a remote weave without a correspondent
weave in the local branch, the merge phase is skipped and the remote weave is
copied into the repository without other action.

The test below highlights a gain of 3x of user time, against a repository with
a history of 2548 revisions and 350 files. The repository is in the same machine,
 which is a Duron 700MHz w/ 384MB of ram.

$ # w/ patch
$ time bzr branch http://kreijack.homelinux.net:8077/bazaar/hgweb_devel/
Branched 1279 revision(s).

real    59m9.511s
user    40m14.090s
sys     1m57.430s

$ # w/o patch
$ time bzr branch http://kreijack.homelinux.net:8077/bazaar/hgweb_devel/
Branched 1279 revision(s).

real    147m34.191s
user    122m10.273s
sys     5m43.247s

Show diffs side-by-side

added added

removed removed

Lines of Context:
101
101
        self.count_total = 0
102
102
        self.count_weaves = 0
103
103
        self.copied_file_ids = set()
 
104
        self.file_ids_names = {}
104
105
        if pb is None:
105
106
            self.pb = bzrlib.ui.ui_factory.progress_bar()
106
107
        else:
217
218
 
218
219
    def _copy_one_weave(self, rev_id, file_id, text_revision):
219
220
        """Copy one file weave, esuring the result contains text_revision."""
 
221
        # check if the revision is already there
 
222
        if file_id in self.file_ids_names.keys( ) and \
 
223
            text_revision in self.file_ids_names[file_id]:
 
224
                return        
220
225
        to_weave = self.to_weaves.get_weave_or_empty(file_id,
221
226
            self.to_branch.get_transaction())
 
227
        if not file_id in self.file_ids_names.keys( ):
 
228
            self.file_ids_names[file_id] = to_weave.names( )
222
229
        if text_revision in to_weave:
223
230
            return
224
231
        from_weave = self.from_weaves.get_weave(file_id,
226
233
        if text_revision not in from_weave:
227
234
            raise MissingText(self.from_branch, text_revision, file_id)
228
235
        mutter('copy file {%s} modified in {%s}', file_id, rev_id)
229
 
        try:
230
 
            to_weave.join(from_weave)
231
 
        except errors.WeaveParentMismatch:
232
 
            to_weave.reweave(from_weave)
 
236
 
 
237
        if to_weave.numversions() > 0:
 
238
            # destination has contents, must merge
 
239
            try:
 
240
                to_weave.join(from_weave)
 
241
            except errors.WeaveParentMismatch:
 
242
                to_weave.reweave(from_weave)
 
243
        else:
 
244
            # destination is empty, just replace it
 
245
            to_weave = from_weave.copy( )
233
246
        self.to_weaves.put_weave(file_id, to_weave,
234
247
            self.to_branch.get_transaction())
235
248
        self.count_weaves += 1
236
249
        self.copied_file_ids.add(file_id)
 
250
        self.file_ids_names[file_id] = to_weave.names()
237
251
        mutter('copied file {%s}', file_id)
238
252
 
239
253