~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/index.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-05-11 11:47:36 UTC
  • mfrom: (5200.3.8 lock_return)
  • Revision ID: pqm@pqm.ubuntu.com-20100511114736-mc1sq9zyo3vufec7
(lifeless) Provide a consistent interface to Tree, Branch,
 Repository where lock methods return an object with an unlock method to
 unlock the lock. This breaks the API for Branch,
 Repository on their lock_write methods. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2011 Canonical Ltd
 
1
# Copyright (C) 2007-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
31
31
 
32
32
from bzrlib.lazy_import import lazy_import
33
33
lazy_import(globals(), """
34
 
from bzrlib import (
35
 
    bisect_multi,
36
 
    revision as _mod_revision,
37
 
    trace,
38
 
    )
 
34
from bzrlib import trace
 
35
from bzrlib.bisect_multi import bisect_multi_bytes
 
36
from bzrlib.revision import NULL_REVISION
 
37
from bzrlib.trace import mutter
39
38
""")
40
39
from bzrlib import (
41
40
    debug,
70
69
class GraphIndexBuilder(object):
71
70
    """A builder that can build a GraphIndex.
72
71
 
73
 
    The resulting graph has the structure::
 
72
    The resulting graph has the structure:
74
73
 
75
 
      _SIGNATURE OPTIONS NODES NEWLINE
76
 
      _SIGNATURE     := 'Bazaar Graph Index 1' NEWLINE
77
 
      OPTIONS        := 'node_ref_lists=' DIGITS NEWLINE
78
 
      NODES          := NODE*
79
 
      NODE           := KEY NULL ABSENT? NULL REFERENCES NULL VALUE NEWLINE
80
 
      KEY            := Not-whitespace-utf8
81
 
      ABSENT         := 'a'
82
 
      REFERENCES     := REFERENCE_LIST (TAB REFERENCE_LIST){node_ref_lists - 1}
83
 
      REFERENCE_LIST := (REFERENCE (CR REFERENCE)*)?
84
 
      REFERENCE      := DIGITS  ; digits is the byte offset in the index of the
85
 
                                ; referenced key.
86
 
      VALUE          := no-newline-no-null-bytes
 
74
    _SIGNATURE OPTIONS NODES NEWLINE
 
75
    _SIGNATURE     := 'Bazaar Graph Index 1' NEWLINE
 
76
    OPTIONS        := 'node_ref_lists=' DIGITS NEWLINE
 
77
    NODES          := NODE*
 
78
    NODE           := KEY NULL ABSENT? NULL REFERENCES NULL VALUE NEWLINE
 
79
    KEY            := Not-whitespace-utf8
 
80
    ABSENT         := 'a'
 
81
    REFERENCES     := REFERENCE_LIST (TAB REFERENCE_LIST){node_ref_lists - 1}
 
82
    REFERENCE_LIST := (REFERENCE (CR REFERENCE)*)?
 
83
    REFERENCE      := DIGITS  ; digits is the byte offset in the index of the
 
84
                              ; referenced key.
 
85
    VALUE          := no-newline-no-null-bytes
87
86
    """
88
87
 
89
88
    def __init__(self, reference_lists=0, key_elements=1):
185
184
        :param value: The value associate with this key. Must not contain
186
185
            newlines or null characters.
187
186
        :return: (node_refs, absent_references)
188
 
        
189
 
            * node_refs: basically a packed form of 'references' where all
190
 
              iterables are tuples
191
 
            * absent_references: reference keys that are not in self._nodes.
192
 
              This may contain duplicates if the same key is referenced in
193
 
              multiple lists.
 
187
            node_refs   basically a packed form of 'references' where all
 
188
                        iterables are tuples
 
189
            absent_references   reference keys that are not in self._nodes.
 
190
                                This may contain duplicates if the same key is
 
191
                                referenced in multiple lists.
194
192
        """
195
193
        as_st = StaticTuple.from_sequence
196
194
        self._check_key(key)
221
219
        :param references: An iterable of iterables of keys. Each is a
222
220
            reference to another key.
223
221
        :param value: The value to associate with the key. It may be any
224
 
            bytes as long as it does not contain \\0 or \\n.
 
222
            bytes as long as it does not contain \0 or \n.
225
223
        """
226
224
        (node_refs,
227
225
         absent_references) = self._check_key_ref_value(key, references, value)
245
243
        """
246
244
        
247
245
    def finish(self):
248
 
        """Finish the index.
249
 
 
250
 
        :returns: cStringIO holding the full context of the index as it 
251
 
        should be written to disk.
252
 
        """
253
246
        lines = [_SIGNATURE]
254
247
        lines.append(_OPTION_NODE_REFS + str(self.reference_lists) + '\n')
255
248
        lines.append(_OPTION_KEY_ELEMENTS + str(self._key_length) + '\n')
451
444
            # We already did this
452
445
            return
453
446
        if 'index' in debug.debug_flags:
454
 
            trace.mutter('Reading entire index %s',
455
 
                          self._transport.abspath(self._name))
 
447
            mutter('Reading entire index %s', self._transport.abspath(self._name))
456
448
        if stream is None:
457
449
            stream = self._transport.get(self._name)
458
450
            if self._base_offset != 0:
470
462
        trailers = 0
471
463
        pos = stream.tell()
472
464
        lines = stream.read().split('\n')
473
 
        # GZ 2009-09-20: Should really use a try/finally block to ensure close
474
465
        stream.close()
475
466
        del lines[-1]
476
467
        _, _, _, trailers = self._parse_lines(lines, pos)
679
670
        if self._nodes is not None:
680
671
            return self._iter_entries_from_total_buffer(keys)
681
672
        else:
682
 
            return (result[1] for result in bisect_multi.bisect_multi_bytes(
 
673
            return (result[1] for result in bisect_multi_bytes(
683
674
                self._lookup_keys_via_location, self._size, keys))
684
675
 
685
676
    def iter_entries_prefix(self, keys):
1296
1287
    def get_parent_map(self, keys):
1297
1288
        """See graph.StackedParentsProvider.get_parent_map"""
1298
1289
        search_keys = set(keys)
1299
 
        if _mod_revision.NULL_REVISION in search_keys:
1300
 
            search_keys.discard(_mod_revision.NULL_REVISION)
1301
 
            found_parents = {_mod_revision.NULL_REVISION:[]}
 
1290
        if NULL_REVISION in search_keys:
 
1291
            search_keys.discard(NULL_REVISION)
 
1292
            found_parents = {NULL_REVISION:[]}
1302
1293
        else:
1303
1294
            found_parents = {}
1304
1295
        for index, key, value, refs in self.iter_entries(search_keys):
1305
1296
            parents = refs[0]
1306
1297
            if not parents:
1307
 
                parents = (_mod_revision.NULL_REVISION,)
 
1298
                parents = (NULL_REVISION,)
1308
1299
            found_parents[key] = parents
1309
1300
        return found_parents
1310
1301
 
1442
1433
        """
1443
1434
        indices_info = zip(self._index_names, self._indices)
1444
1435
        if 'index' in debug.debug_flags:
1445
 
            trace.mutter('CombinedGraphIndex reordering: currently %r, '
1446
 
                         'promoting %r', indices_info, hit_indices)
 
1436
            mutter('CombinedGraphIndex reordering: currently %r, promoting %r',
 
1437
                   indices_info, hit_indices)
1447
1438
        hit_names = []
1448
1439
        unhit_names = []
1449
1440
        new_hit_indices = []
1466
1457
        self._indices = new_hit_indices + unhit_indices
1467
1458
        self._index_names = hit_names + unhit_names
1468
1459
        if 'index' in debug.debug_flags:
1469
 
            trace.mutter('CombinedGraphIndex reordered: %r', self._indices)
 
1460
            mutter('CombinedGraphIndex reordered: %r', self._indices)
1470
1461
        return hit_names
1471
1462
 
1472
1463
    def _move_to_front_by_name(self, hit_names):