/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 bzrlib/chk_map.py

  • Committer: Robert Collins
  • Date: 2010-05-06 11:08:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506110810-h3j07fh5gmw54s25
Cleaner matcher matching revised unlocking protocol.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2008, 2009, 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
38
38
"""
39
39
 
40
40
import heapq
 
41
import threading
41
42
 
42
43
from bzrlib import lazy_import
43
44
lazy_import.lazy_import(globals(), """
59
60
# If each line is 50 bytes, and you have 255 internal pages, with 255-way fan
60
61
# out, it takes 3.1MB to cache the layer.
61
62
_PAGE_CACHE_SIZE = 4*1024*1024
62
 
# We are caching bytes so len(value) is perfectly accurate
63
 
_page_cache = lru_cache.LRUSizeCache(_PAGE_CACHE_SIZE)
 
63
# Per thread caches for 2 reasons:
 
64
# - in the server we may be serving very different content, so we get less
 
65
#   cache thrashing.
 
66
# - we avoid locking on every cache lookup.
 
67
_thread_caches = threading.local()
 
68
# The page cache.
 
69
_thread_caches.page_cache = None
 
70
 
 
71
def _get_cache():
 
72
    """Get the per-thread page cache.
 
73
 
 
74
    We need a function to do this because in a new thread the _thread_caches
 
75
    threading.local object does not have the cache initialized yet.
 
76
    """
 
77
    page_cache = getattr(_thread_caches, 'page_cache', None)
 
78
    if page_cache is None:
 
79
        # We are caching bytes so len(value) is perfectly accurate
 
80
        page_cache = lru_cache.LRUSizeCache(_PAGE_CACHE_SIZE)
 
81
        _thread_caches.page_cache = page_cache
 
82
    return page_cache
 
83
 
64
84
 
65
85
def clear_cache():
66
 
    _page_cache.clear()
 
86
    _get_cache().clear()
 
87
 
67
88
 
68
89
# If a ChildNode falls below this many bytes, we check for a remap
69
90
_INTERESTING_NEW_SIZE = 50
161
182
 
162
183
    def _read_bytes(self, key):
163
184
        try:
164
 
            return _page_cache[key]
 
185
            return _get_cache()[key]
165
186
        except KeyError:
166
187
            stream = self._store.get_record_stream([key], 'unordered', True)
167
188
            bytes = stream.next().get_bytes_as('fulltext')
168
 
            _page_cache[key] = bytes
 
189
            _get_cache()[key] = bytes
169
190
            return bytes
170
191
 
171
192
    def _dump_tree(self, include_keys=False):
671
692
        the key/value pairs.
672
693
    """
673
694
 
674
 
    __slots__ = ('_common_serialised_prefix', '_serialise_key')
 
695
    __slots__ = ('_common_serialised_prefix',)
675
696
 
676
697
    def __init__(self, search_key_func=None):
677
698
        Node.__init__(self)
678
699
        # All of the keys in this leaf node share this common prefix
679
700
        self._common_serialised_prefix = None
680
 
        self._serialise_key = '\x00'.join
681
701
        if search_key_func is None:
682
702
            self._search_key_func = _search_key_plain
683
703
        else:
867
887
                raise AssertionError('%r must be known' % self._search_prefix)
868
888
            return self._search_prefix, [("", self)]
869
889
 
 
890
    _serialise_key = '\x00'.join
 
891
 
870
892
    def serialise(self, store):
871
893
        """Serialise the LeafNode to store.
872
894
 
901
923
        bytes = ''.join(lines)
902
924
        if len(bytes) != self._current_size():
903
925
            raise AssertionError('Invalid _current_size')
904
 
        _page_cache.add(self._key, bytes)
 
926
        _get_cache().add(self._key, bytes)
905
927
        return [self._key]
906
928
 
907
929
    def refs(self):
1143
1165
            found_keys = set()
1144
1166
            for key in keys:
1145
1167
                try:
1146
 
                    bytes = _page_cache[key]
 
1168
                    bytes = _get_cache()[key]
1147
1169
                except KeyError:
1148
1170
                    continue
1149
1171
                else:
1174
1196
                    prefix, node_key_filter = keys[record.key]
1175
1197
                    node_and_filters.append((node, node_key_filter))
1176
1198
                    self._items[prefix] = node
1177
 
                    _page_cache.add(record.key, bytes)
 
1199
                    _get_cache().add(record.key, bytes)
1178
1200
                for info in node_and_filters:
1179
1201
                    yield info
1180
1202
 
1300
1322
            lines.append(serialised[prefix_len:])
1301
1323
        sha1, _, _ = store.add_lines((None,), (), lines)
1302
1324
        self._key = StaticTuple("sha1:" + sha1,).intern()
1303
 
        _page_cache.add(self._key, ''.join(lines))
 
1325
        _get_cache().add(self._key, ''.join(lines))
1304
1326
        yield self._key
1305
1327
 
1306
1328
    def _search_key(self, key):
1489
1511
        self._state = None
1490
1512
 
1491
1513
    def _read_nodes_from_store(self, keys):
1492
 
        # We chose not to use _page_cache, because we think in terms of records
1493
 
        # to be yielded. Also, we expect to touch each page only 1 time during
1494
 
        # this code. (We may want to evaluate saving the raw bytes into the
1495
 
        # page cache, which would allow a working tree update after the fetch
1496
 
        # to not have to read the bytes again.)
 
1514
        # We chose not to use _get_cache(), because we think in
 
1515
        # terms of records to be yielded. Also, we expect to touch each page
 
1516
        # only 1 time during this code. (We may want to evaluate saving the
 
1517
        # raw bytes into the page cache, which would allow a working tree
 
1518
        # update after the fetch to not have to read the bytes again.)
1497
1519
        as_st = StaticTuple.from_sequence
1498
1520
        stream = self._store.get_record_stream(keys, 'unordered', True)
1499
1521
        for record in stream: