~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/repository.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-01-18 01:16:25 UTC
  • mfrom: (3184.1.13 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20080118011625-465mgy0mhdz1jiky
(robertc) Reduce traffic when requesting revision streams from a
        smart server (3 MB to 172 bytes for a full bzr.dev pull)
        (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
        """
49
49
        transport = self._backing_transport.clone(path)
50
50
        bzrdir = BzrDir.open_from_transport(transport)
51
 
        repository = bzrdir.open_repository()
52
 
        return self.do_repository_request(repository, *args)
 
51
        # Save the repository for use with do_body.
 
52
        self._repository = bzrdir.open_repository()
 
53
        return self.do_repository_request(self._repository, *args)
 
54
 
 
55
    def do_repository_request(self, repository, *args):
 
56
        """Override to provide an implementation for a verb."""
 
57
        # No-op for verbs that take bodies (None as a result indicates a body
 
58
        # is expected)
 
59
        return None
53
60
 
54
61
 
55
62
class SmartServerRepositoryGetParentMap(SmartServerRepositoryRequest):
307
314
 
308
315
 
309
316
class SmartServerRepositoryStreamKnitDataForRevisions(SmartServerRepositoryRequest):
 
317
    """Bzr <= 1.1 streaming pull, buffers all data on server."""
310
318
 
311
319
    def do_repository_request(self, repository, *revision_ids):
312
320
        repository.lock_read()
316
324
            repository.unlock()
317
325
 
318
326
    def _do_repository_request(self, repository, revision_ids):
319
 
        stream = repository.get_data_stream(revision_ids)
 
327
        stream = repository.get_data_stream_for_search(
 
328
            repository.revision_ids_to_search_result(set(revision_ids)))
320
329
        buffer = StringIO()
321
330
        pack = ContainerSerialiser()
322
331
        buffer.write(pack.begin())
330
339
 
331
340
 
332
341
class SmartServerRepositoryStreamRevisionsChunked(SmartServerRepositoryRequest):
 
342
    """Bzr 1.1+ streaming pull."""
333
343
 
334
 
    def do_repository_request(self, repository, *revision_ids):
 
344
    def do_body(self, body_bytes):
 
345
        lines = body_bytes.split('\n')
 
346
        start_keys = set(lines[0].split(' '))
 
347
        exclude_keys = set(lines[1].split(' '))
 
348
        revision_count = int(lines[2])
 
349
        repository = self._repository
335
350
        repository.lock_read()
336
351
        try:
337
 
            stream = repository.get_data_stream(revision_ids)
 
352
            search = repository.get_graph()._make_breadth_first_searcher(
 
353
                start_keys)
 
354
            while True:
 
355
                try:
 
356
                    next_revs = search.next()
 
357
                except StopIteration:
 
358
                    break
 
359
                search.stop_searching_any(exclude_keys.intersection(next_revs))
 
360
            search_result = search.get_result()
 
361
            if search_result.get_recipe()[2] != revision_count:
 
362
                # we got back a different amount of data than expected, this
 
363
                # gets reported as NoSuchRevision, because less revisions
 
364
                # indicates missing revisions, and more should never happen as
 
365
                # the excludes list considers ghosts and ensures that ghost
 
366
                # filling races are not a problem.
 
367
                return FailedSmartServerResponse(('NoSuchRevision',))
 
368
            stream = repository.get_data_stream_for_search(search_result)
338
369
        except Exception:
339
370
            repository.unlock()
340
371
            raise
348
379
            for name_tuple, bytes in stream:
349
380
                yield pack.bytes_record(bytes, [name_tuple])
350
381
        except errors.RevisionNotPresent, e:
 
382
            # This shouldn't be able to happen, but as we don't buffer
 
383
            # everything it can in theory happen.
351
384
            yield FailedSmartServerResponse(('NoSuchRevision', e.revision_id))
352
385
        repository.unlock()
353
386
        pack.end()