104
104
pb = bzrlib.ui.ui_factory.progress_bar()
106
# XXX: Is there any reason why we couldn't make this accept a generator
107
# and build a list as it finds things to copy?
108
ids = list(ids) # Make sure we don't have a generator, since we iterate 2 times
109
105
pb.update('preparing to copy')
112
if not self.has_id(file_id):
113
to_copy.append(file_id)
114
return self._do_copy(other, to_copy, pb, permit_failure=permit_failure)
116
def _do_copy(self, other, to_copy, pb, permit_failure=False):
117
"""This is the standard copying mechanism, just get them one at
118
a time from remote, and store them locally.
120
:param other: Another Store object
121
:param to_copy: A list of entry ids to copy
122
:param pb: A ProgressBar object to display completion status.
123
:param permit_failure: Allow missing entries to be ignored
124
:return: (n_copied, [failed])
125
The number of entries copied, and a list of failed entries.
127
# This should be updated to use add_multi() rather than
128
# the current methods of buffering requests.
129
# One question, is it faster to queue up 1-10 and then copy 1-10
130
# then queue up 11-20, copy 11-20
131
# or to queue up 1-10, copy 1, queue 11, copy 2, etc?
132
# sort of pipeline versus batch.
134
# We can't use self._transport.copy_to because we don't know
135
# whether the local tree is in the same format as other
137
def buffer_requests():
139
buffered_requests = []
140
for fileid in to_copy:
142
f = other.get(fileid)
150
buffered_requests.append((f, fileid))
151
if len(buffered_requests) > self._max_buffered_requests:
152
yield buffered_requests.pop(0)
154
pb.update('copy', count, len(to_copy))
156
for req in buffered_requests:
159
pb.update('copy', count, len(to_copy))
161
assert count == len(to_copy)
163
for f, fileid in buffer_requests():
108
ids = list(ids) # get the list for showing a length.
111
if self.has_id(fileid):
114
self._copy_one(fileid, other, pb)
115
pb.update('copy', count, len(ids))
121
assert count == len(ids)
167
return len(to_copy), failed
125
def _copy_one(self, fileid, other, pb):
126
"""Most generic copy-one object routine.
128
Subclasses can override this to provide an optimised
129
copy between their own instances. Such overriden routines
130
should call this if they have no optimised facility for a
133
f = other.get(fileid)
170
137
class TransportStore(Store):
171
138
"""A TransportStore is a Store superclass for Stores that use Transports."""
173
_max_buffered_requests = 10
175
140
def add(self, f, fileid, suffix=None):
176
141
"""Add contents of a file into the store.