~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/btree_index.py

  • Committer: John Arbash Meinel
  • Date: 2010-02-17 17:11:16 UTC
  • mfrom: (4797.2.17 2.1)
  • mto: (4797.2.18 2.1)
  • mto: This revision was merged to the branch mainline in revision 5055.
  • Revision ID: john@arbash-meinel.com-20100217171116-h7t9223ystbnx5h8
merge bzr.2.1 in preparation for NEWS entry.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008 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
31
31
    index,
32
32
    lru_cache,
33
33
    osutils,
 
34
    static_tuple,
34
35
    trace,
35
36
    )
36
37
from bzrlib.index import _OPTION_NODE_REFS, _OPTION_KEY_ELEMENTS, _OPTION_LEN
159
160
        :param value: The value to associate with the key. It may be any
160
161
            bytes as long as it does not contain \0 or \n.
161
162
        """
 
163
        # Ensure that 'key' is a StaticTuple
 
164
        key = static_tuple.StaticTuple.from_sequence(key).intern()
162
165
        # we don't care about absent_references
163
166
        node_refs, _ = self._check_key_ref_value(key, references, value)
164
167
        if key in self._nodes:
165
168
            raise errors.BadIndexDuplicateKey(key, self)
166
 
        # TODO: StaticTuple
167
 
        self._nodes[key] = (node_refs, value)
168
 
        self._keys.add(key)
 
169
        self._nodes[key] = static_tuple.StaticTuple(node_refs, value)
169
170
        if self._nodes_by_key is not None and self._key_length > 1:
170
171
            self._update_nodes_by_key(key, value, node_refs)
171
 
        if len(self._keys) < self._spill_at:
 
172
        if len(self._nodes) < self._spill_at:
172
173
            return
173
174
        self._spill_mem_keys_to_disk()
174
175
 
203
204
                self._backing_indices[backing_pos] = None
204
205
        else:
205
206
            self._backing_indices.append(new_backing)
206
 
        self._keys = set()
207
207
        self._nodes = {}
208
208
        self._nodes_by_key = None
209
209
 
411
411
            # Special case the first node as it may be prefixed
412
412
            node = row.spool.read(_PAGE_SIZE)
413
413
            result.write(node[reserved:])
414
 
            result.write("\x00" * (reserved - position))
 
414
            if len(node) == _PAGE_SIZE:
 
415
                result.write("\x00" * (reserved - position))
415
416
            position = 0 # Only the root row actually has an offset
416
417
            copied_len = osutils.pumpfile(row.spool, result)
417
418
            if copied_len != (row.nodes - 1) * _PAGE_SIZE:
462
463
            efficient order for the index (keys iteration order in this case).
463
464
        """
464
465
        keys = set(keys)
465
 
        local_keys = keys.intersection(self._keys)
 
466
        # Note: We don't use keys.intersection() here. If you read the C api,
 
467
        #       set.intersection(other) special cases when other is a set and
 
468
        #       will iterate the smaller of the two and lookup in the other.
 
469
        #       It does *not* do this for any other type (even dict, unlike
 
470
        #       some other set functions.) Since we expect keys is generally <<
 
471
        #       self._nodes, it is faster to iterate over it in a list
 
472
        #       comprehension
 
473
        nodes = self._nodes
 
474
        local_keys = [key for key in keys if key in nodes]
466
475
        if self.reference_lists:
467
476
            for key in local_keys:
468
 
                node = self._nodes[key]
 
477
                node = nodes[key]
469
478
                yield self, key, node[1], node[0]
470
479
        else:
471
480
            for key in local_keys:
472
 
                node = self._nodes[key]
 
481
                node = nodes[key]
473
482
                yield self, key, node[1]
474
483
        # Find things that are in backing indices that have not been handled
475
484
        # yet.
585
594
 
586
595
        For InMemoryGraphIndex the estimate is exact.
587
596
        """
588
 
        return len(self._keys) + sum(backing.key_count() for backing in
 
597
        return len(self._nodes) + sum(backing.key_count() for backing in
589
598
            self._backing_indices if backing is not None)
590
599
 
591
600
    def validate(self):
623
632
    def _parse_lines(self, lines):
624
633
        nodes = []
625
634
        self.offset = int(lines[1][7:])
 
635
        as_st = static_tuple.StaticTuple.from_sequence
626
636
        for line in lines[2:]:
627
637
            if line == '':
628
638
                break
629
 
            # TODO: Switch to StaticTuple here.
630
 
            nodes.append(tuple(map(intern, line.split('\0'))))
 
639
            nodes.append(as_st(map(intern, line.split('\0'))).intern())
631
640
        return nodes
632
641
 
633
642