~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/store/versioned/__init__.py

Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
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)
120
120
 
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.
 
123
 
 
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.
 
127
        """
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)
125
131
            return weave
 
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)
131
139
        else:
132
 
            w = self._versionedfile_class(self.filename(file_id),
 
140
            w = self._versionedfile_class(_filename,
133
141
                                          self._transport,
134
142
                                          self._file_mode,
135
143
                                          create=False,
148
156
        w = self.get_weave(file_id, transaction)
149
157
        return w.get_lines(rev_id)
150
158
    
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)
157
 
        return weave
158
 
 
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.
 
162
        
 
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.
 
166
        """
 
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)
162
171
        try:
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.
169
180
                raise
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)
174
185
        return weave
175
186
 
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
 
193
        # versioned files.
 
194
        _filename = self.filename(file_id)
178
195
        try:
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)
 
203
            return weave
182
204
 
183
205
    @deprecated_method(zero_eight)
184
206
    def put_weave(self, file_id, weave, transaction):