~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Martin Pool
  • Date: 2006-06-20 07:55:43 UTC
  • mfrom: (1798 +trunk)
  • mto: This revision was merged to the branch mainline in revision 1799.
  • Revision ID: mbp@sourcefrog.net-20060620075543-b10f6575d4a4fa32
[merge] bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
import os
23
23
from cStringIO import StringIO
24
24
import urllib
 
25
from warnings import warn
25
26
 
 
27
from bzrlib import errors
26
28
from bzrlib.weavefile import read_weave, write_weave_v5
27
29
from bzrlib.weave import WeaveFile, Weave
28
30
from bzrlib.store import TransportStore
29
31
from bzrlib.atomicfile import AtomicFile
30
 
from bzrlib.errors import NoSuchFile, FileExists
31
 
from bzrlib.symbol_versioning import *
 
32
from bzrlib.symbol_versioning import (deprecated_method,
 
33
        zero_eight)
32
34
from bzrlib.trace import mutter
33
35
import bzrlib.ui
34
36
 
112
114
        fn = self.filename(file_id)
113
115
        try:
114
116
            return self._transport.put(fn, f, mode=self._file_mode)
115
 
        except NoSuchFile:
 
117
        except errors.NoSuchFile:
116
118
            if not self._prefixed:
117
119
                raise
118
120
            self._transport.mkdir(os.path.dirname(fn), mode=self._dir_mode)
119
121
            return self._transport.put(fn, f, mode=self._file_mode)
120
122
 
121
 
    def get_weave(self, file_id, transaction):
 
123
    def get_weave(self, file_id, transaction, _filename=None):
 
124
        """Return the VersionedFile for file_id.
 
125
 
 
126
        :param _filename: filename that would be returned from self.filename for
 
127
        file_id. This is used to reduce duplicate filename calculations when
 
128
        using 'get_weave_or_empty'. FOR INTERNAL USE ONLY.
 
129
        """
122
130
        weave = transaction.map.find_weave(file_id)
123
131
        if weave is not None:
124
132
            #mutter("cache hit in %s for %s", self, file_id)
125
133
            return weave
 
134
        if _filename is None:
 
135
            _filename = self.filename(file_id)
126
136
        if transaction.writeable():
127
 
            w = self._versionedfile_class(self.filename(file_id), self._transport, self._file_mode,
 
137
            w = self._versionedfile_class(_filename, self._transport, self._file_mode,
128
138
                                          **self._versionedfile_kwargs)
129
139
            transaction.map.add_weave(file_id, w)
130
140
            transaction.register_dirty(w)
131
141
        else:
132
 
            w = self._versionedfile_class(self.filename(file_id),
 
142
            w = self._versionedfile_class(_filename,
133
143
                                          self._transport,
134
144
                                          self._file_mode,
135
145
                                          create=False,
148
158
        w = self.get_weave(file_id, transaction)
149
159
        return w.get_lines(rev_id)
150
160
    
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):
 
161
    def _make_new_versionedfile(self, file_id, transaction,
 
162
        known_missing=False, _filename=None):
 
163
        """Make a new versioned file.
 
164
        
 
165
        :param _filename: filename that would be returned from self.filename for
 
166
        file_id. This is used to reduce duplicate filename calculations when
 
167
        using 'get_weave_or_empty'. FOR INTERNAL USE ONLY.
 
168
        """
 
169
        if not known_missing and self.has_id(file_id):
161
170
            self.delete(file_id, transaction)
 
171
        if _filename is None:
 
172
            _filename = self.filename(file_id)
162
173
        try:
163
 
            weave = self._versionedfile_class(self.filename(file_id), self._transport, self._file_mode, create=True,
 
174
            # we try without making the directory first because thats optimising
 
175
            # for the common case.
 
176
            weave = self._versionedfile_class(_filename, self._transport, self._file_mode, create=True,
164
177
                                              **self._versionedfile_kwargs)
165
 
        except NoSuchFile:
 
178
        except errors.NoSuchFile:
166
179
            if not self._prefixed:
167
 
                # unexpected error - NoSuchFile is raised on a missing dir only and that
168
 
                # only occurs when we are prefixed.
 
180
                # unexpected error - NoSuchFile is expected to be raised on a
 
181
                # missing dir only and that only occurs when we are prefixed.
169
182
                raise
170
183
            self._transport.mkdir(self.hash_prefix(file_id), mode=self._dir_mode)
171
 
            weave = self._versionedfile_class(self.filename(file_id), self._transport, 
 
184
            weave = self._versionedfile_class(_filename, self._transport, 
172
185
                                              self._file_mode, create=True,
173
186
                                              **self._versionedfile_kwargs)
174
187
        return weave
175
188
 
176
189
    def get_weave_or_empty(self, file_id, transaction):
177
 
        """Return a weave, or an empty one if it doesn't exist.""" 
 
190
        """Return a weave, or an empty one if it doesn't exist."""
 
191
        # This is typically used from 'commit' and 'fetch/push/pull' where 
 
192
        # we scan across many versioned files once. As such the small overhead
 
193
        # of calculating the filename before doing a cache lookup is more than
 
194
        # compensated for by not calculating the filename when making new
 
195
        # versioned files.
 
196
        _filename = self.filename(file_id)
178
197
        try:
179
 
            return self.get_weave(file_id, transaction)
180
 
        except NoSuchFile:
181
 
            return self._new_weave(file_id, transaction)
 
198
            return self.get_weave(file_id, transaction, _filename=_filename)
 
199
        except errors.NoSuchFile:
 
200
            weave = self._make_new_versionedfile(file_id, transaction,
 
201
                known_missing=True, _filename=_filename)
 
202
            transaction.map.add_weave(file_id, weave)
 
203
            # has to be dirty - its able to mutate on its own.
 
204
            transaction.register_dirty(weave)
 
205
            return weave
182
206
 
183
207
    @deprecated_method(zero_eight)
184
208
    def put_weave(self, file_id, weave, transaction):
233
257
            warn("Please pass to_transaction into "
234
258
                 "versioned_store.copy_all_ids.", stacklevel=2)
235
259
        if not store_from.listable():
236
 
            raise UnlistableStore(store_from)
 
260
            raise errors.UnlistableStore(store_from)
237
261
        ids = []
238
262
        for count, file_id in enumerate(store_from):
239
263
            if pb: