~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/btree_index.py

  • Committer: Martin Pool
  • Date: 2010-01-29 10:36:23 UTC
  • mto: This revision was merged to the branch mainline in revision 4992.
  • Revision ID: mbp@sourcefrog.net-20100129103623-hywka5hymo5z13jw
Change url to canonical.com or wiki, plus some doc improvements in passing

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2008 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
567
567
                    else:
568
568
                        # yield keys
569
569
                        for value in key_dict.itervalues():
570
 
                            yield (self, ) + tuple(value)
 
570
                            yield (self, ) + value
571
571
            else:
572
572
                yield (self, ) + key_dict
573
573
 
647
647
    memory except when very large walks are done.
648
648
    """
649
649
 
650
 
    def __init__(self, transport, name, size, unlimited_cache=False,
651
 
                 offset=0):
 
650
    def __init__(self, transport, name, size, unlimited_cache=False):
652
651
        """Create a B+Tree index object on the index name.
653
652
 
654
653
        :param transport: The transport to read data for the index from.
661
660
        :param unlimited_cache: If set to True, then instead of using an
662
661
            LRUCache with size _NODE_CACHE_SIZE, we will use a dict and always
663
662
            cache all leaf nodes.
664
 
        :param offset: The start of the btree index data isn't byte 0 of the
665
 
            file. Instead it starts at some point later.
666
663
        """
667
664
        self._transport = transport
668
665
        self._name = name
670
667
        self._file = None
671
668
        self._recommended_pages = self._compute_recommended_pages()
672
669
        self._root_node = None
673
 
        self._base_offset = offset
674
670
        # Default max size is 100,000 leave values
675
671
        self._leaf_value_cache = None # lru_cache.LRUCache(100*1000)
676
672
        if unlimited_cache:
1498
1494
        # list of (offset, length) regions of the file that should, evenually
1499
1495
        # be read in to data_ranges, either from 'bytes' or from the transport
1500
1496
        ranges = []
1501
 
        base_offset = self._base_offset
1502
1497
        for index in nodes:
1503
 
            offset = (index * _PAGE_SIZE)
 
1498
            offset = index * _PAGE_SIZE
1504
1499
            size = _PAGE_SIZE
1505
1500
            if index == 0:
1506
1501
                # Root node - special case
1510
1505
                    # The only case where we don't know the size, is for very
1511
1506
                    # small indexes. So we read the whole thing
1512
1507
                    bytes = self._transport.get_bytes(self._name)
1513
 
                    num_bytes = len(bytes)
1514
 
                    self._size = num_bytes - base_offset
 
1508
                    self._size = len(bytes)
1515
1509
                    # the whole thing should be parsed out of 'bytes'
1516
 
                    ranges = [(start, min(_PAGE_SIZE, num_bytes - start))
1517
 
                        for start in xrange(base_offset, num_bytes, _PAGE_SIZE)]
 
1510
                    ranges.append((0, len(bytes)))
1518
1511
                    break
1519
1512
            else:
1520
1513
                if offset > self._size:
1522
1515
                                         ' of the file %s > %s'
1523
1516
                                         % (offset, self._size))
1524
1517
                size = min(size, self._size - offset)
1525
 
            ranges.append((base_offset + offset, size))
 
1518
            ranges.append((offset, size))
1526
1519
        if not ranges:
1527
1520
            return
1528
1521
        elif bytes is not None:
1529
1522
            # already have the whole file
1530
 
            data_ranges = [(start, bytes[start:start+size])
1531
 
                           for start, size in ranges]
 
1523
            data_ranges = [(start, bytes[start:start+_PAGE_SIZE])
 
1524
                           for start in xrange(0, len(bytes), _PAGE_SIZE)]
1532
1525
        elif self._file is None:
1533
1526
            data_ranges = self._transport.readv(self._name, ranges)
1534
1527
        else:
1537
1530
                self._file.seek(offset)
1538
1531
                data_ranges.append((offset, self._file.read(size)))
1539
1532
        for offset, data in data_ranges:
1540
 
            offset -= base_offset
1541
1533
            if offset == 0:
1542
1534
                # extract the header
1543
1535
                offset, data = self._parse_header_from_bytes(data)