~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/remote.py

Tags: bzr-1.9
(mbp) prepare 1.9final

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
    RemoteTCPTransport, etc.
62
62
    """
63
63
 
64
 
    # When making a readv request, cap it at requesting 5MB of data
65
 
    _max_readv_bytes = 5*1024*1024
66
 
 
67
64
    # IMPORTANT FOR IMPLEMENTORS: RemoteTransport MUST NOT be given encoding
68
65
    # responsibilities: Put those on SmartClient or similar. This is vital for
69
66
    # the ability to support multiple versions of the smart protocol over time:
315
312
                               limit=self._max_readv_combine,
316
313
                               fudge_factor=self._bytes_to_read_before_seek))
317
314
 
318
 
        # now that we've coallesced things, avoid making enormous requests
319
 
        requests = []
320
 
        cur_request = []
321
 
        cur_len = 0
322
 
        for c in coalesced:
323
 
            if c.length + cur_len > self._max_readv_bytes:
324
 
                requests.append(cur_request)
325
 
                cur_request = [c]
326
 
                cur_len = c.length
327
 
                continue
328
 
            cur_request.append(c)
329
 
            cur_len += c.length
330
 
        if cur_request:
331
 
            requests.append(cur_request)
332
 
        if 'hpss' in debug.debug_flags:
333
 
            trace.mutter('%s.readv %s offsets => %s coalesced'
334
 
                         ' => %s requests (%s)',
335
 
                         self.__class__.__name__, len(offsets), len(coalesced),
336
 
                         len(requests), sum(map(len, requests)))
337
 
        # Cache the results, but only until they have been fulfilled
338
 
        data_map = {}
339
 
        # turn the list of offsets into a single stack to iterate
 
315
        try:
 
316
            result = self._client.call_with_body_readv_array(
 
317
                ('readv', self._remote_path(relpath),),
 
318
                [(c.start, c.length) for c in coalesced])
 
319
            resp, response_handler = result
 
320
        except errors.ErrorFromSmartServer, err:
 
321
            self._translate_error(err)
 
322
 
 
323
        if resp[0] != 'readv':
 
324
            # This should raise an exception
 
325
            response_handler.cancel_read_body()
 
326
            raise errors.UnexpectedSmartServerResponse(resp)
 
327
 
 
328
        return self._handle_response(offsets, coalesced, response_handler)
 
329
 
 
330
    def _handle_response(self, offsets, coalesced, response_handler):
 
331
        # turn the list of offsets into a stack
340
332
        offset_stack = iter(offsets)
341
 
        # using a list so it can be modified when passing down and coming back
342
 
        next_offset = [offset_stack.next()]
343
 
        for cur_request in requests:
344
 
            try:
345
 
                result = self._client.call_with_body_readv_array(
346
 
                    ('readv', self._remote_path(relpath),),
347
 
                    [(c.start, c.length) for c in cur_request])
348
 
                resp, response_handler = result
349
 
            except errors.ErrorFromSmartServer, err:
350
 
                self._translate_error(err)
351
 
 
352
 
            if resp[0] != 'readv':
353
 
                # This should raise an exception
354
 
                response_handler.cancel_read_body()
355
 
                raise errors.UnexpectedSmartServerResponse(resp)
356
 
 
357
 
            for res in self._handle_response(offset_stack, cur_request,
358
 
                                             response_handler,
359
 
                                             data_map,
360
 
                                             next_offset):
361
 
                yield res
362
 
 
363
 
    def _handle_response(self, offset_stack, coalesced, response_handler,
364
 
                         data_map, next_offset):
365
 
        cur_offset_and_size = next_offset[0]
 
333
        cur_offset_and_size = offset_stack.next()
366
334
        # FIXME: this should know how many bytes are needed, for clarity.
367
335
        data = response_handler.read_body_bytes()
 
336
        # Cache the results, but only until they have been fulfilled
 
337
        data_map = {}
368
338
        data_offset = 0
369
339
        for c_offset in coalesced:
370
340
            if len(data) < c_offset.length:
383
353
                #       not have a real string.
384
354
                if key == cur_offset_and_size:
385
355
                    yield cur_offset_and_size[0], this_data
386
 
                    cur_offset_and_size = next_offset[0] = offset_stack.next()
 
356
                    cur_offset_and_size = offset_stack.next()
387
357
                else:
388
358
                    data_map[key] = this_data
389
359
            data_offset += c_offset.length
392
362
            while cur_offset_and_size in data_map:
393
363
                this_data = data_map.pop(cur_offset_and_size)
394
364
                yield cur_offset_and_size[0], this_data
395
 
                cur_offset_and_size = next_offset[0] = offset_stack.next()
 
365
                cur_offset_and_size = offset_stack.next()
396
366
 
397
367
    def rename(self, rel_from, rel_to):
398
368
        self._call('rename',