118
118
self._transport.mkdir(os.path.dirname(fn), mode=self._dir_mode)
119
119
return self._transport.put(fn, f, mode=self._file_mode)
121
def get_weave(self, file_id, transaction):
121
def get_weave(self, file_id, transaction, _filename=None):
122
"""Return the VersionedFile for file_id.
124
:param _filename: filename that would be returned from self.filename for
125
file_id. This is used to reduce duplicate filename calculations when
126
using 'get_weave_or_empty'. FOR INTERNAL USE ONLY.
122
128
weave = transaction.map.find_weave(file_id)
123
129
if weave is not None:
124
130
#mutter("cache hit in %s for %s", self, file_id)
132
if _filename is None:
133
_filename = self.filename(file_id)
126
134
if transaction.writeable():
127
w = self._versionedfile_class(self.filename(file_id), self._transport, self._file_mode,
135
w = self._versionedfile_class(_filename, self._transport, self._file_mode,
128
136
**self._versionedfile_kwargs)
129
137
transaction.map.add_weave(file_id, w)
130
138
transaction.register_dirty(w)
132
w = self._versionedfile_class(self.filename(file_id),
140
w = self._versionedfile_class(_filename,
148
156
w = self.get_weave(file_id, transaction)
149
157
return w.get_lines(rev_id)
151
def _new_weave(self, file_id, transaction):
152
"""Make a new weave for file_id and return it."""
153
weave = self._make_new_versionedfile(file_id, transaction)
154
transaction.map.add_weave(file_id, weave)
155
# has to be dirty - its able to mutate on its own.
156
transaction.register_dirty(weave)
159
def _make_new_versionedfile(self, file_id, transaction):
160
if self.has_id(file_id):
159
def _make_new_versionedfile(self, file_id, transaction,
160
known_missing=False, _filename=None):
161
"""Make a new versioned file.
163
:param _filename: filename that would be returned from self.filename for
164
file_id. This is used to reduce duplicate filename calculations when
165
using 'get_weave_or_empty'. FOR INTERNAL USE ONLY.
167
if not known_missing and self.has_id(file_id):
161
168
self.delete(file_id, transaction)
169
if _filename is None:
170
_filename = self.filename(file_id)
163
weave = self._versionedfile_class(self.filename(file_id), self._transport, self._file_mode, create=True,
172
# we try without making the directory first because thats optimising
173
# for the common case.
174
weave = self._versionedfile_class(_filename, self._transport, self._file_mode, create=True,
164
175
**self._versionedfile_kwargs)
165
176
except NoSuchFile:
166
177
if not self._prefixed:
167
# unexpected error - NoSuchFile is raised on a missing dir only and that
168
# only occurs when we are prefixed.
178
# unexpected error - NoSuchFile is expected to be raised on a
179
# missing dir only and that only occurs when we are prefixed.
170
181
self._transport.mkdir(self.hash_prefix(file_id), mode=self._dir_mode)
171
weave = self._versionedfile_class(self.filename(file_id), self._transport,
182
weave = self._versionedfile_class(_filename, self._transport,
172
183
self._file_mode, create=True,
173
184
**self._versionedfile_kwargs)
176
187
def get_weave_or_empty(self, file_id, transaction):
177
"""Return a weave, or an empty one if it doesn't exist."""
188
"""Return a weave, or an empty one if it doesn't exist."""
189
# This is typically used from 'commit' and 'fetch/push/pull' where
190
# we scan across many versioned files once. As such the small overhead
191
# of calculating the filename before doing a cache lookup is more than
192
# compensated for by not calculating the filename when making new
194
_filename = self.filename(file_id)
179
return self.get_weave(file_id, transaction)
196
return self.get_weave(file_id, transaction, _filename=_filename)
180
197
except NoSuchFile:
181
return self._new_weave(file_id, transaction)
198
weave = self._make_new_versionedfile(file_id, transaction,
199
known_missing=True, _filename=_filename)
200
transaction.map.add_weave(file_id, weave)
201
# has to be dirty - its able to mutate on its own.
202
transaction.register_dirty(weave)
183
205
@deprecated_method(zero_eight)
184
206
def put_weave(self, file_id, weave, transaction):