~jelmer/brz/colocated-spec

« back to all changes in this revision

Viewing changes to breezy/hashcache.py

  • Committer: Jelmer Vernooij
  • Date: 2017-05-22 00:56:52 UTC
  • mfrom: (6621.2.26 py3_pokes)
  • Revision ID: jelmer@jelmer.uk-20170522005652-yjahcr9hwmjkno7n
Merge Python3 porting work ('py3 pokes')

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
import stat
36
36
import time
37
37
 
38
 
from breezy import (
 
38
from . import (
39
39
    atomicfile,
40
40
    errors,
41
41
    filters as _mod_filters,
42
42
    osutils,
43
43
    trace,
44
44
    )
 
45
from .sixish import (
 
46
    text_type,
 
47
    )
45
48
 
46
49
 
47
50
FP_MTIME_COLUMN = 1
95
98
            parameters and returns a stack of ContentFilters.
96
99
            If None, no content filtering is performed.
97
100
        """
98
 
        self.root = osutils.safe_unicode(root)
99
 
        self.root_utf8 = self.root.encode('utf8') # where is the filesystem encoding ?
 
101
        if not isinstance(root, text_type):
 
102
            raise ValueError("Base dir for hashcache must be text")
 
103
        self.root = root
100
104
        self.hit_count = 0
101
105
        self.miss_count = 0
102
106
        self.stat_count = 0
105
109
        self.update_count = 0
106
110
        self._cache = {}
107
111
        self._mode = mode
108
 
        self._cache_file_name = osutils.safe_unicode(cache_file_name)
 
112
        self._cache_file_name = cache_file_name
109
113
        self._filter_provider = content_filter_stack_provider
110
114
 
111
115
    def cache_file_name(self):
125
129
        Obsolete entries are those where the file has been modified or deleted
126
130
        since the entry was inserted.
127
131
        """
128
 
        # FIXME optimisation opportunity, on linux [and check other oses]:
129
 
        # rather than iteritems order, stat in inode order.
130
 
        prep = [(ce[1][3], path, ce) for (path, ce) in self._cache.iteritems()]
131
 
        prep.sort()
132
 
 
133
 
        for inum, path, cache_entry in prep:
 
132
        # Stat in inode order as optimisation for at least linux.
 
133
        def inode_order(path_and_cache):
 
134
            return path_and_cache[1][1][3]
 
135
        for inum, path, cache_entry in sorted(self._cache, key=inode_order):
134
136
            abspath = osutils.pathjoin(self.root, path)
135
137
            fp = self._fingerprint(abspath)
136
138
            self.stat_count += 1
146
148
    def get_sha1(self, path, stat_value=None):
147
149
        """Return the sha1 of a file.
148
150
        """
149
 
        if path.__class__ is str:
150
 
            abspath = osutils.pathjoin(self.root_utf8, path)
151
 
        else:
152
 
            abspath = osutils.pathjoin(self.root, path)
 
151
        abspath = osutils.pathjoin(self.root, path)
153
152
        self.stat_count += 1
154
153
        file_fp = self._fingerprint(abspath, stat_value)
155
154
 
182
181
                filters = self._filter_provider(path=path, file_id=None)
183
182
            digest = self._really_sha1_file(abspath, filters)
184
183
        elif stat.S_ISLNK(mode):
185
 
            target = osutils.readlink(osutils.safe_unicode(abspath))
 
184
            target = osutils.readlink(abspath)
186
185
            digest = osutils.sha_string(target.encode('UTF-8'))
187
186
        else:
188
187
            raise errors.BzrError("file %r: unknown file stat mode: %o"
256
255
        fn = self.cache_file_name()
257
256
        try:
258
257
            inf = file(fn, 'rb', buffering=65000)
259
 
        except IOError, e:
 
258
        except IOError as e:
260
259
            trace.mutter("failed to open %s: %s", fn, e)
261
260
            # better write it now so it is valid
262
261
            self.needs_write = True
287
286
                trace.warning("bad sha1 in hashcache: %r" % sha1)
288
287
                continue
289
288
 
290
 
            fp = tuple(map(long, fields[1:]))
 
289
            fp = tuple(map(int, fields[1:]))
291
290
 
292
291
            self._cache[path] = (sha1, fp)
293
292
 
315
314
            return None
316
315
        # we discard any high precision because it's not reliable; perhaps we
317
316
        # could do better on some systems?
318
 
        return (stat_value.st_size, long(stat_value.st_mtime),
319
 
                long(stat_value.st_ctime), stat_value.st_ino,
 
317
        return (stat_value.st_size, int(stat_value.st_mtime),
 
318
                int(stat_value.st_ctime), stat_value.st_ino,
320
319
                stat_value.st_dev, stat_value.st_mode)