/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/hashcache.py

  • Committer: Jelmer Vernooij
  • Date: 2017-06-10 01:35:53 UTC
  • mto: (6670.4.8 move-bzr)
  • mto: This revision was merged to the branch mainline in revision 6681.
  • Revision ID: jelmer@jelmer.uk-20170610013553-560y7mn3su4pp763
Fix remaining tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
 
17
from __future__ import absolute_import
 
18
 
17
19
# TODO: Up-front, stat all files in order and remove those which are deleted or
18
20
# out-of-date.  Don't actually re-read them until they're needed.  That ought
19
21
# to bring all the inodes into core so that future stats to them are fast, and
33
35
import stat
34
36
import time
35
37
 
36
 
from bzrlib import (
 
38
from . import (
37
39
    atomicfile,
38
40
    errors,
39
41
    filters as _mod_filters,
40
42
    osutils,
41
43
    trace,
42
44
    )
 
45
from .sixish import (
 
46
    text_type,
 
47
    viewitems,
 
48
    )
43
49
 
44
50
 
45
51
FP_MTIME_COLUMN = 1
93
99
            parameters and returns a stack of ContentFilters.
94
100
            If None, no content filtering is performed.
95
101
        """
96
 
        self.root = osutils.safe_unicode(root)
97
 
        self.root_utf8 = self.root.encode('utf8') # where is the filesystem encoding ?
 
102
        if not isinstance(root, text_type):
 
103
            raise ValueError("Base dir for hashcache must be text")
 
104
        self.root = root
98
105
        self.hit_count = 0
99
106
        self.miss_count = 0
100
107
        self.stat_count = 0
103
110
        self.update_count = 0
104
111
        self._cache = {}
105
112
        self._mode = mode
106
 
        self._cache_file_name = osutils.safe_unicode(cache_file_name)
 
113
        self._cache_file_name = cache_file_name
107
114
        self._filter_provider = content_filter_stack_provider
108
115
 
109
116
    def cache_file_name(self):
123
130
        Obsolete entries are those where the file has been modified or deleted
124
131
        since the entry was inserted.
125
132
        """
126
 
        # FIXME optimisation opportunity, on linux [and check other oses]:
127
 
        # rather than iteritems order, stat in inode order.
128
 
        prep = [(ce[1][3], path, ce) for (path, ce) in self._cache.iteritems()]
129
 
        prep.sort()
130
 
 
131
 
        for inum, path, cache_entry in prep:
 
133
        # Stat in inode order as optimisation for at least linux.
 
134
        def inode_order(path_and_cache):
 
135
            return path_and_cache[1][1][3]
 
136
        for path, cache_val in sorted(viewitems(self._cache), key=inode_order):
132
137
            abspath = osutils.pathjoin(self.root, path)
133
138
            fp = self._fingerprint(abspath)
134
139
            self.stat_count += 1
135
140
 
136
 
            cache_fp = cache_entry[1]
137
 
 
138
 
            if (not fp) or (cache_fp != fp):
 
141
            if not fp or cache_val[1] != fp:
139
142
                # not here or not a regular file anymore
140
143
                self.removed_count += 1
141
144
                self.needs_write = True
144
147
    def get_sha1(self, path, stat_value=None):
145
148
        """Return the sha1 of a file.
146
149
        """
147
 
        if path.__class__ is str:
148
 
            abspath = osutils.pathjoin(self.root_utf8, path)
149
 
        else:
150
 
            abspath = osutils.pathjoin(self.root, path)
 
150
        abspath = osutils.pathjoin(self.root, path)
151
151
        self.stat_count += 1
152
152
        file_fp = self._fingerprint(abspath, stat_value)
153
153
 
180
180
                filters = self._filter_provider(path=path, file_id=None)
181
181
            digest = self._really_sha1_file(abspath, filters)
182
182
        elif stat.S_ISLNK(mode):
183
 
            target = osutils.readlink(osutils.safe_unicode(abspath))
 
183
            target = osutils.readlink(abspath)
184
184
            digest = osutils.sha_string(target.encode('UTF-8'))
185
185
        else:
186
186
            raise errors.BzrError("file %r: unknown file stat mode: %o"
228
228
        try:
229
229
            outf.write(CACHE_HEADER)
230
230
 
231
 
            for path, c  in self._cache.iteritems():
 
231
            for path, c  in viewitems(self._cache):
232
232
                line_info = [path.encode('utf-8'), '// ', c[0], ' ']
233
233
                line_info.append(' '.join([str(fld) for fld in c[1]]))
234
234
                line_info.append('\n')
254
254
        fn = self.cache_file_name()
255
255
        try:
256
256
            inf = file(fn, 'rb', buffering=65000)
257
 
        except IOError, e:
 
257
        except IOError as e:
258
258
            trace.mutter("failed to open %s: %s", fn, e)
259
259
            # better write it now so it is valid
260
260
            self.needs_write = True
285
285
                trace.warning("bad sha1 in hashcache: %r" % sha1)
286
286
                continue
287
287
 
288
 
            fp = tuple(map(long, fields[1:]))
 
288
            fp = tuple(map(int, fields[1:]))
289
289
 
290
290
            self._cache[path] = (sha1, fp)
291
291
 
 
292
        # GZ 2009-09-20: Should really use a try/finally block to ensure close
 
293
        inf.close()
 
294
 
292
295
        self.needs_write = False
293
296
 
294
297
    def _cutoff_time(self):
310
313
            return None
311
314
        # we discard any high precision because it's not reliable; perhaps we
312
315
        # could do better on some systems?
313
 
        return (stat_value.st_size, long(stat_value.st_mtime),
314
 
                long(stat_value.st_ctime), stat_value.st_ino,
 
316
        return (stat_value.st_size, int(stat_value.st_mtime),
 
317
                int(stat_value.st_ctime), stat_value.st_ino,
315
318
                stat_value.st_dev, stat_value.st_mode)