~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/btree_index.py

  • Committer: John Arbash Meinel
  • Date: 2009-10-20 19:46:46 UTC
  • mfrom: (4759 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4771.
  • Revision ID: john@arbash-meinel.com-20091020194646-wnqpd15qs19y28z7
Merge bzr.dev 4759, bringing in static_tuple and streaming improvements.

Show diffs side-by-side

added added

removed removed

Lines of Context:
163
163
        node_refs, _ = self._check_key_ref_value(key, references, value)
164
164
        if key in self._nodes:
165
165
            raise errors.BadIndexDuplicateKey(key, self)
 
166
        # TODO: StaticTuple
166
167
        self._nodes[key] = (node_refs, value)
167
168
        self._keys.add(key)
168
169
        if self._nodes_by_key is not None and self._key_length > 1:
625
626
        for line in lines[2:]:
626
627
            if line == '':
627
628
                break
 
629
            # TODO: Switch to StaticTuple here.
628
630
            nodes.append(tuple(map(intern, line.split('\0'))))
629
631
        return nodes
630
632
 
636
638
    memory except when very large walks are done.
637
639
    """
638
640
 
639
 
    def __init__(self, transport, name, size):
 
641
    def __init__(self, transport, name, size, unlimited_cache=False):
640
642
        """Create a B+Tree index object on the index name.
641
643
 
642
644
        :param transport: The transport to read data for the index from.
646
648
            the initial read (to read the root node header) can be done
647
649
            without over-reading even on empty indices, and on small indices
648
650
            allows single-IO to read the entire index.
 
651
        :param unlimited_cache: If set to True, then instead of using an
 
652
            LRUCache with size _NODE_CACHE_SIZE, we will use a dict and always
 
653
            cache all leaf nodes.
649
654
        """
650
655
        self._transport = transport
651
656
        self._name = name
655
660
        self._root_node = None
656
661
        # Default max size is 100,000 leave values
657
662
        self._leaf_value_cache = None # lru_cache.LRUCache(100*1000)
658
 
        self._leaf_node_cache = lru_cache.LRUCache(_NODE_CACHE_SIZE)
659
 
        # We could limit this, but even a 300k record btree has only 3k leaf
660
 
        # nodes, and only 20 internal nodes. So the default of 100 nodes in an
661
 
        # LRU would mean we always cache everything anyway, no need to pay the
662
 
        # overhead of LRU
663
 
        self._internal_node_cache = fifo_cache.FIFOCache(100)
 
663
        if unlimited_cache:
 
664
            self._leaf_node_cache = {}
 
665
            self._internal_node_cache = {}
 
666
        else:
 
667
            self._leaf_node_cache = lru_cache.LRUCache(_NODE_CACHE_SIZE)
 
668
            # We use a FIFO here just to prevent possible blowout. However, a
 
669
            # 300k record btree has only 3k leaf nodes, and only 20 internal
 
670
            # nodes. A value of 100 scales to ~100*100*100 = 1M records.
 
671
            self._internal_node_cache = fifo_cache.FIFOCache(100)
664
672
        self._key_count = None
665
673
        self._row_lengths = None
666
674
        self._row_offsets = None # Start of each row, [-1] is the end
698
706
                if start_of_leaves is None:
699
707
                    start_of_leaves = self._row_offsets[-2]
700
708
                if node_pos < start_of_leaves:
701
 
                    self._internal_node_cache.add(node_pos, node)
 
709
                    self._internal_node_cache[node_pos] = node
702
710
                else:
703
 
                    self._leaf_node_cache.add(node_pos, node)
 
711
                    self._leaf_node_cache[node_pos] = node
704
712
            found[node_pos] = node
705
713
        return found
706
714
 
845
853
            new_tips = next_tips
846
854
        return final_offsets
847
855
 
 
856
    def clear_cache(self):
 
857
        """Clear out any cached/memoized values.
 
858
 
 
859
        This can be called at any time, but generally it is used when we have
 
860
        extracted some information, but don't expect to be requesting any more
 
861
        from this index.
 
862
        """
 
863
        # Note that we don't touch self._root_node or self._internal_node_cache
 
864
        # We don't expect either of those to be big, and it can save
 
865
        # round-trips in the future. We may re-evaluate this if InternalNode
 
866
        # memory starts to be an issue.
 
867
        self._leaf_node_cache.clear()
 
868
 
848
869
    def external_references(self, ref_list_num):
849
870
        if self._root_node is None:
850
871
            self._get_root_node()