~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/chk_map.py

  • Committer: Vincent Ladeuil
  • Date: 2012-01-18 14:09:19 UTC
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120118140919-rlvdrhpc0nq1lbwi
Change set/remove to require a lock for the branch config files.

This means that tests (or any plugin for that matter) do not requires an
explicit lock on the branch anymore to change a single option. This also
means the optimisation becomes "opt-in" and as such won't be as
spectacular as it may be and/or harder to get right (nothing fails
anymore).

This reduces the diff by ~300 lines.

Code/tests that were updating more than one config option is still taking
a lock to at least avoid some IOs and demonstrate the benefits through
the decreased number of hpss calls.

The duplication between BranchStack and BranchOnlyStack will be removed
once the same sharing is in place for local config files, at which point
the Stack class itself may be able to host the changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2008-2011 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
37
37
 
38
38
"""
39
39
 
 
40
from __future__ import absolute_import
 
41
 
40
42
import heapq
41
43
import threading
42
44
 
44
46
lazy_import.lazy_import(globals(), """
45
47
from bzrlib import (
46
48
    errors,
47
 
    versionedfile,
48
49
    )
49
50
""")
50
51
from bzrlib import (
 
52
    errors,
51
53
    lru_cache,
52
54
    osutils,
53
55
    registry,
90
92
_INTERESTING_NEW_SIZE = 50
91
93
# If a ChildNode shrinks by more than this amount, we check for a remap
92
94
_INTERESTING_SHRINKAGE_LIMIT = 20
93
 
# If we delete more than this many nodes applying a delta, we check for a remap
94
 
_INTERESTING_DELETES_LIMIT = 5
95
95
 
96
96
 
97
97
def _search_key_plain(key):
135
135
            into the map; if old_key is not None, then the old mapping
136
136
            of old_key is removed.
137
137
        """
138
 
        delete_count = 0
 
138
        has_deletes = False
139
139
        # Check preconditions first.
140
140
        as_st = StaticTuple.from_sequence
141
141
        new_items = set([as_st(key) for (old, key, value) in delta
148
148
        for old, new, value in delta:
149
149
            if old is not None and old != new:
150
150
                self.unmap(old, check_remap=False)
151
 
                delete_count += 1
 
151
                has_deletes = True
152
152
        for old, new, value in delta:
153
153
            if new is not None:
154
154
                self.map(new, value)
155
 
        if delete_count > _INTERESTING_DELETES_LIMIT:
156
 
            trace.mutter("checking remap as %d deletions", delete_count)
 
155
        if has_deletes:
157
156
            self._check_remap()
158
157
        return self._save()
159
158
 
573
572
        """Check if nodes can be collapsed."""
574
573
        self._ensure_root()
575
574
        if type(self._root_node) is InternalNode:
576
 
            self._root_node._check_remap(self._store)
 
575
            self._root_node = self._root_node._check_remap(self._store)
577
576
 
578
577
    def _save(self):
579
578
        """Save the map completely.
923
922
        bytes = ''.join(lines)
924
923
        if len(bytes) != self._current_size():
925
924
            raise AssertionError('Invalid _current_size')
926
 
        _get_cache().add(self._key, bytes)
 
925
        _get_cache()[self._key] = bytes
927
926
        return [self._key]
928
927
 
929
928
    def refs(self):
1196
1195
                    prefix, node_key_filter = keys[record.key]
1197
1196
                    node_and_filters.append((node, node_key_filter))
1198
1197
                    self._items[prefix] = node
1199
 
                    _get_cache().add(record.key, bytes)
 
1198
                    _get_cache()[record.key] = bytes
1200
1199
                for info in node_and_filters:
1201
1200
                    yield info
1202
1201
 
1322
1321
            lines.append(serialised[prefix_len:])
1323
1322
        sha1, _, _ = store.add_lines((None,), (), lines)
1324
1323
        self._key = StaticTuple("sha1:" + sha1,).intern()
1325
 
        _get_cache().add(self._key, ''.join(lines))
 
1324
        _get_cache()[self._key] = ''.join(lines)
1326
1325
        yield self._key
1327
1326
 
1328
1327
    def _search_key(self, key):
1372
1371
        return self._search_prefix
1373
1372
 
1374
1373
    def unmap(self, store, key, check_remap=True):
1375
 
        """Remove key from this node and it's children."""
 
1374
        """Remove key from this node and its children."""
1376
1375
        if not len(self._items):
1377
1376
            raise AssertionError("can't unmap in an empty InternalNode.")
1378
1377
        children = [node for node, _
1727
1726
 
1728
1727
try:
1729
1728
    from bzrlib._chk_map_pyx import (
 
1729
        _bytes_to_text_key,
1730
1730
        _search_key_16,
1731
1731
        _search_key_255,
1732
1732
        _deserialise_leaf_node,
1735
1735
except ImportError, e:
1736
1736
    osutils.failed_to_load_extension(e)
1737
1737
    from bzrlib._chk_map_py import (
 
1738
        _bytes_to_text_key,
1738
1739
        _search_key_16,
1739
1740
        _search_key_255,
1740
1741
        _deserialise_leaf_node,