~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/hashcache.py

  • Committer: John Arbash Meinel
  • Date: 2009-03-06 20:42:40 UTC
  • mto: This revision was merged to the branch mainline in revision 4088.
  • Revision ID: john@arbash-meinel.com-20090306204240-mzjavv31z3gu1x7i
Fix a small bug in setup.py when an extension fails to build

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
# TODO: Up-front, stat all files in order and remove those which are deleted or
18
18
# out-of-date.  Don't actually re-read them until they're needed.  That ought
29
29
 
30
30
CACHE_HEADER = "### bzr hashcache v5\n"
31
31
 
32
 
import os
33
 
import stat
34
 
import time
 
32
import os, stat, time
35
33
 
36
 
from bzrlib import (
37
 
    atomicfile,
38
 
    errors,
39
 
    filters as _mod_filters,
40
 
    osutils,
41
 
    trace,
42
 
    )
 
34
from bzrlib.osutils import sha_file, sha_string, pathjoin, safe_unicode
 
35
from bzrlib.trace import mutter, warning
 
36
from bzrlib.atomicfile import AtomicFile
 
37
from bzrlib.errors import BzrError
43
38
 
44
39
 
45
40
FP_MTIME_COLUMN = 1
84
79
    """
85
80
    needs_write = False
86
81
 
87
 
    def __init__(self, root, cache_file_name, mode=None,
88
 
            content_filter_stack_provider=None):
89
 
        """Create a hash cache in base dir, and set the file mode to mode.
90
 
 
91
 
        :param content_filter_stack_provider: a function that takes a
92
 
            path (relative to the top of the tree) and a file-id as
93
 
            parameters and returns a stack of ContentFilters.
94
 
            If None, no content filtering is performed.
95
 
        """
96
 
        self.root = osutils.safe_unicode(root)
 
82
    def __init__(self, root, cache_file_name, mode=None):
 
83
        """Create a hash cache in base dir, and set the file mode to mode."""
 
84
        self.root = safe_unicode(root)
97
85
        self.root_utf8 = self.root.encode('utf8') # where is the filesystem encoding ?
98
86
        self.hit_count = 0
99
87
        self.miss_count = 0
103
91
        self.update_count = 0
104
92
        self._cache = {}
105
93
        self._mode = mode
106
 
        self._cache_file_name = osutils.safe_unicode(cache_file_name)
107
 
        self._filter_provider = content_filter_stack_provider
 
94
        self._cache_file_name = safe_unicode(cache_file_name)
108
95
 
109
96
    def cache_file_name(self):
110
97
        return self._cache_file_name
129
116
        prep.sort()
130
117
 
131
118
        for inum, path, cache_entry in prep:
132
 
            abspath = osutils.pathjoin(self.root, path)
 
119
            abspath = pathjoin(self.root, path)
133
120
            fp = self._fingerprint(abspath)
134
121
            self.stat_count += 1
135
122
 
145
132
        """Return the sha1 of a file.
146
133
        """
147
134
        if path.__class__ is str:
148
 
            abspath = osutils.pathjoin(self.root_utf8, path)
 
135
            abspath = pathjoin(self.root_utf8, path)
149
136
        else:
150
 
            abspath = osutils.pathjoin(self.root, path)
 
137
            abspath = pathjoin(self.root, path)
151
138
        self.stat_count += 1
152
139
        file_fp = self._fingerprint(abspath, stat_value)
153
140
 
174
161
 
175
162
        mode = file_fp[FP_MODE_COLUMN]
176
163
        if stat.S_ISREG(mode):
177
 
            if self._filter_provider is None:
178
 
                filters = []
179
 
            else:
180
 
                filters = self._filter_provider(path=path, file_id=None)
181
 
            digest = self._really_sha1_file(abspath, filters)
 
164
            digest = self._really_sha1_file(abspath)
182
165
        elif stat.S_ISLNK(mode):
183
 
            target = osutils.readlink(osutils.safe_unicode(abspath))
184
 
            digest = osutils.sha_string(target.encode('UTF-8'))
 
166
            digest = sha_string(os.readlink(abspath))
185
167
        else:
186
 
            raise errors.BzrError("file %r: unknown file stat mode: %o"
187
 
                                  % (abspath, mode))
 
168
            raise BzrError("file %r: unknown file stat mode: %o"%(abspath,mode))
188
169
 
189
170
        # window of 3 seconds to allow for 2s resolution on windows,
190
171
        # unsynchronized file servers, etc.
217
198
            self._cache[path] = (digest, file_fp)
218
199
        return digest
219
200
 
220
 
    def _really_sha1_file(self, abspath, filters):
 
201
    def _really_sha1_file(self, abspath):
221
202
        """Calculate the SHA1 of a file by reading the full text"""
222
 
        return _mod_filters.internal_size_sha_file_byname(abspath, filters)[1]
 
203
        return sha_file(file(abspath, 'rb', buffering=65000))
223
204
 
224
205
    def write(self):
225
206
        """Write contents of cache to file."""
226
 
        outf = atomicfile.AtomicFile(self.cache_file_name(), 'wb',
227
 
                                     new_mode=self._mode)
 
207
        outf = AtomicFile(self.cache_file_name(), 'wb', new_mode=self._mode)
228
208
        try:
229
209
            outf.write(CACHE_HEADER)
230
210
 
255
235
        try:
256
236
            inf = file(fn, 'rb', buffering=65000)
257
237
        except IOError, e:
258
 
            trace.mutter("failed to open %s: %s", fn, e)
 
238
            mutter("failed to open %s: %s", fn, e)
259
239
            # better write it now so it is valid
260
240
            self.needs_write = True
261
241
            return
262
242
 
263
243
        hdr = inf.readline()
264
244
        if hdr != CACHE_HEADER:
265
 
            trace.mutter('cache header marker not found at top of %s;'
266
 
                         ' discarding cache', fn)
 
245
            mutter('cache header marker not found at top of %s;'
 
246
                   ' discarding cache', fn)
267
247
            self.needs_write = True
268
248
            return
269
249
 
271
251
            pos = l.index('// ')
272
252
            path = l[:pos].decode('utf-8')
273
253
            if path in self._cache:
274
 
                trace.warning('duplicated path %r in cache' % path)
 
254
                warning('duplicated path %r in cache' % path)
275
255
                continue
276
256
 
277
257
            pos += 3
278
258
            fields = l[pos:].split(' ')
279
259
            if len(fields) != 7:
280
 
                trace.warning("bad line in hashcache: %r" % l)
 
260
                warning("bad line in hashcache: %r" % l)
281
261
                continue
282
262
 
283
263
            sha1 = fields[0]
284
264
            if len(sha1) != 40:
285
 
                trace.warning("bad sha1 in hashcache: %r" % sha1)
 
265
                warning("bad sha1 in hashcache: %r" % sha1)
286
266
                continue
287
267
 
288
268
            fp = tuple(map(long, fields[1:]))