~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/pack_repo.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-02-23 17:00:36 UTC
  • mfrom: (4032.1.4 jam-integration)
  • Revision ID: pqm@pqm.ubuntu.com-20090223170036-3q1v68ewdt8i0to5
(Marius Kruger) Remove all trailing whitespace and add tests to
        enforce this.

Show diffs side-by-side

added added

removed removed

Lines of Context:
81
81
 
82
82
class PackCommitBuilder(CommitBuilder):
83
83
    """A subclass of CommitBuilder to add texts with pack semantics.
84
 
    
 
84
 
85
85
    Specifically this uses one knit object rather than one knit object per
86
86
    added text, reducing memory and object pressure.
87
87
    """
102
102
 
103
103
class PackRootCommitBuilder(RootCommitBuilder):
104
104
    """A subclass of RootCommitBuilder to add texts with pack semantics.
105
 
    
 
105
 
106
106
    Specifically this uses one knit object rather than one knit object per
107
107
    added text, reducing memory and object pressure.
108
108
    """
163
163
 
164
164
    def _check_references(self):
165
165
        """Make sure our external references are present.
166
 
        
 
166
 
167
167
        Packs are allowed to have deltas whose base is not in the pack, but it
168
168
        must be present somewhere in this collection.  It is not allowed to
169
169
        have deltas based on a fallback repository.
374
374
            mutter('%s: create_pack: pack stream open: %s%s t+%6.3fs',
375
375
                time.ctime(), self.upload_transport.base, self.random_name,
376
376
                time.time() - self.start_time)
377
 
        # A list of byte sequences to be written to the new pack, and the 
378
 
        # aggregate size of them.  Stored as a list rather than separate 
 
377
        # A list of byte sequences to be written to the new pack, and the
 
378
        # aggregate size of them.  Stored as a list rather than separate
379
379
        # variables so that the _write_data closure below can update them.
380
380
        self._buffer = [[], 0]
381
 
        # create a callable for adding data 
 
381
        # create a callable for adding data
382
382
        #
383
383
        # robertc says- this is a closure rather than a method on the object
384
384
        # so that the variables are locals, and faster than accessing object
510
510
            mutter('%s: create_pack: wrote %s index: %s%s t+%6.3fs',
511
511
                time.ctime(), label, self.upload_transport.base,
512
512
                self.random_name, time.time() - self.start_time)
513
 
        # Replace the writable index on this object with a readonly, 
 
513
        # Replace the writable index on this object with a readonly,
514
514
        # presently unloaded index. We should alter
515
515
        # the index layer to make its finish() error if add_node is
516
516
        # subsequently used. RBC
525
525
    such as 'revision index'.
526
526
 
527
527
    A CombinedIndex provides an index on a single key space built up
528
 
    from several on-disk indices.  The AggregateIndex builds on this 
 
528
    from several on-disk indices.  The AggregateIndex builds on this
529
529
    to provide a knit access layer, and allows having up to one writable
530
530
    index within the collection.
531
531
    """
571
571
 
572
572
        Future searches on the aggregate index will seach this new index
573
573
        before all previously inserted indices.
574
 
        
 
574
 
575
575
        :param index: An Index for the pack.
576
576
        :param pack: A Pack instance.
577
577
        """
585
585
 
586
586
        There can be at most one writable index at any time.  Any
587
587
        modifications made to the knit are put into this index.
588
 
        
 
588
 
589
589
        :param index: An index from the pack parameter.
590
590
        :param pack: A Pack instance.
591
591
        """
608
608
 
609
609
    def remove_index(self, index, pack):
610
610
        """Remove index from the indices used to answer queries.
611
 
        
 
611
 
612
612
        :param index: An index from the pack parameter.
613
613
        :param pack: A Pack instance.
614
614
        """
689
689
        This does little more than a bulk copy of data. One key difference
690
690
        is that data with the same item key across multiple packs is elided
691
691
        from the output. The new pack is written into the current pack store
692
 
        along with its indices, and the name added to the pack names. The 
 
692
        along with its indices, and the name added to the pack names. The
693
693
        source packs are not altered and are not required to be in the current
694
694
        pack collection.
695
695
 
914
914
        nodes = sorted(nodes)
915
915
        # how to map this into knit.py - or knit.py into this?
916
916
        # we don't want the typical knit logic, we want grouping by pack
917
 
        # at this point - perhaps a helper library for the following code 
 
917
        # at this point - perhaps a helper library for the following code
918
918
        # duplication points?
919
919
        request_groups = {}
920
920
        for index, key, value in nodes:
1020
1020
 
1021
1021
    def _least_readv_node_readv(self, nodes):
1022
1022
        """Generate request groups for nodes using the least readv's.
1023
 
        
 
1023
 
1024
1024
        :param nodes: An iterable of graph index nodes.
1025
1025
        :return: Total node count and an iterator of the data needed to perform
1026
1026
            readvs to obtain the data for nodes. Each item yielded by the
1137
1137
 
1138
1138
class ReconcilePacker(Packer):
1139
1139
    """A packer which regenerates indices etc as it copies.
1140
 
    
 
1140
 
1141
1141
    This is used by ``bzr reconcile`` to cause parent text pointers to be
1142
1142
    regenerated.
1143
1143
    """
1166
1166
        # 1) generate the ideal index
1167
1167
        repo = self._pack_collection.repo
1168
1168
        ancestors = dict([(key[0], tuple(ref[0] for ref in refs[0])) for
1169
 
            _1, key, _2, refs in 
 
1169
            _1, key, _2, refs in
1170
1170
            self.new_pack.revision_index.iter_all_entries()])
1171
1171
        ideal_index = repo._generate_text_key_index(self._text_refs, ancestors)
1172
1172
        # 2) generate a text_nodes list that contains all the deltas that can
1178
1178
        text_index_map, text_nodes = self._get_text_nodes()
1179
1179
        for node in text_nodes:
1180
1180
            # 0 - index
1181
 
            # 1 - key 
 
1181
            # 1 - key
1182
1182
            # 2 - value
1183
1183
            # 3 - refs
1184
1184
            try:
1279
1279
 
1280
1280
class RepositoryPackCollection(object):
1281
1281
    """Management of packs within a repository.
1282
 
    
 
1282
 
1283
1283
    :ivar _names: map of {pack_name: (index_size,)}
1284
1284
    """
1285
1285
 
1287
1287
                 pack_transport, index_builder_class, index_class):
1288
1288
        """Create a new RepositoryPackCollection.
1289
1289
 
1290
 
        :param transport: Addresses the repository base directory 
 
1290
        :param transport: Addresses the repository base directory
1291
1291
            (typically .bzr/repository/).
1292
1292
        :param index_transport: Addresses the directory containing indices.
1293
1293
        :param upload_transport: Addresses the directory into which packs are written
1321
1321
 
1322
1322
    def add_pack_to_memory(self, pack):
1323
1323
        """Make a Pack object available to the repository to satisfy queries.
1324
 
        
 
1324
 
1325
1325
        :param pack: A Pack object.
1326
1326
        """
1327
1327
        if pack.name in self._packs_by_name:
1333
1333
        self.inventory_index.add_index(pack.inventory_index, pack)
1334
1334
        self.text_index.add_index(pack.text_index, pack)
1335
1335
        self.signature_index.add_index(pack.signature_index, pack)
1336
 
        
 
1336
 
1337
1337
    def all_packs(self):
1338
1338
        """Return a list of all the Pack objects this repository has.
1339
1339
 
1348
1348
 
1349
1349
    def autopack(self):
1350
1350
        """Pack the pack collection incrementally.
1351
 
        
 
1351
 
1352
1352
        This will not attempt global reorganisation or recompression,
1353
1353
        rather it will just ensure that the total number of packs does
1354
1354
        not grow without bound. It uses the _max_pack_count method to
1391
1391
                # group their data with the relevant commit, and that may
1392
1392
                # involve rewriting ancient history - which autopack tries to
1393
1393
                # avoid. Alternatively we could not group the data but treat
1394
 
                # each of these as having a single revision, and thus add 
 
1394
                # each of these as having a single revision, and thus add
1395
1395
                # one revision for each to the total revision count, to get
1396
1396
                # a matching distribution.
1397
1397
                continue
1444
1444
 
1445
1445
    def lock_names(self):
1446
1446
        """Acquire the mutex around the pack-names index.
1447
 
        
 
1447
 
1448
1448
        This cannot be used in the middle of a read-only transaction on the
1449
1449
        repository.
1450
1450
        """
1602
1602
 
1603
1603
    def _iter_disk_pack_index(self):
1604
1604
        """Iterate over the contents of the pack-names index.
1605
 
        
 
1605
 
1606
1606
        This is used when loading the list from disk, and before writing to
1607
1607
        detect updates from others during our write operation.
1608
1608
        :return: An iterator of the index contents.
1623
1623
 
1624
1624
    def _max_pack_count(self, total_revisions):
1625
1625
        """Return the maximum number of packs to use for total revisions.
1626
 
        
 
1626
 
1627
1627
        :param total_revisions: The total number of revisions in the
1628
1628
            repository.
1629
1629
        """
1684
1684
 
1685
1685
    def _remove_pack_from_memory(self, pack):
1686
1686
        """Remove pack from the packs accessed by this repository.
1687
 
        
 
1687
 
1688
1688
        Only affects memory state, until self._save_pack_names() is invoked.
1689
1689
        """
1690
1690
        self._names.pop(pack.name)
1815
1815
        try:
1816
1816
            builder = self._index_builder_class()
1817
1817
            disk_nodes, deleted_nodes, new_nodes = self._diff_pack_names()
1818
 
            # TODO: handle same-name, index-size-changes here - 
 
1818
            # TODO: handle same-name, index-size-changes here -
1819
1819
            # e.g. use the value from disk, not ours, *unless* we're the one
1820
1820
            # changing it.
1821
1821
            for key, value in disk_nodes:
1980
1980
 
1981
1981
class KnitPackRepository(KnitRepository):
1982
1982
    """Repository with knit objects stored inside pack containers.
1983
 
    
 
1983
 
1984
1984
    The layering for a KnitPackRepository is:
1985
1985
 
1986
1986
    Graph        |  HPSS    | Repository public layer |
2000
2000
      pack file. The GraphIndex layer works in N-tuples and is unaware of any
2001
2001
      semantic value.
2002
2002
    ===================================================
2003
 
    
 
2003
 
2004
2004
    """
2005
2005
 
2006
2006
    def __init__(self, _format, a_bzrdir, control_files, _commit_builder_class,
2039
2039
            data_access=self._pack_collection.text_index.data_access,
2040
2040
            max_delta_chain=200)
2041
2041
        # True when the repository object is 'write locked' (as opposed to the
2042
 
        # physical lock only taken out around changes to the pack-names list.) 
 
2042
        # physical lock only taken out around changes to the pack-names list.)
2043
2043
        # Another way to represent this would be a decorator around the control
2044
2044
        # files object that presents logical locks as physical ones - if this
2045
2045
        # gets ugly consider that alternative design. RBC 20071011
2264
2264
        builder = self.index_builder_class()
2265
2265
        files = [('pack-names', builder.finish())]
2266
2266
        utf8_files = [('format', self.get_format_string())]
2267
 
        
 
2267
 
2268
2268
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
2269
2269
        return self.open(a_bzrdir=a_bzrdir, _found=True)
2270
2270
 
2271
2271
    def open(self, a_bzrdir, _found=False, _override_transport=None):
2272
2272
        """See RepositoryFormat.open().
2273
 
        
 
2273
 
2274
2274
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
2275
2275
                                    repository at a slightly different url
2276
2276
                                    than normal. I.e. during 'upgrade'.
2362
2362
        if not getattr(target_format, 'supports_tree_reference', False):
2363
2363
            raise errors.BadConversionTarget(
2364
2364
                'Does not support nested trees', target_format)
2365
 
            
 
2365
 
2366
2366
    def get_format_string(self):
2367
2367
        """See RepositoryFormat.get_format_string()."""
2368
2368
        return "Bazaar pack repository format 1 with subtree support (needs bzr 0.92)\n"
2708
2708
        if not getattr(target_format, 'supports_tree_reference', False):
2709
2709
            raise errors.BadConversionTarget(
2710
2710
                'Does not support nested trees', target_format)
2711
 
            
 
2711
 
2712
2712
    def get_format_string(self):
2713
2713
        """See RepositoryFormat.get_format_string()."""
2714
2714
        return ("Bazaar development format 2 with subtree support "