~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/pack_repo.py

remove all trailing whitespace from bzr source

Show diffs side-by-side

added added

removed removed

Lines of Context:
80
80
 
81
81
class PackCommitBuilder(CommitBuilder):
82
82
    """A subclass of CommitBuilder to add texts with pack semantics.
83
 
    
 
83
 
84
84
    Specifically this uses one knit object rather than one knit object per
85
85
    added text, reducing memory and object pressure.
86
86
    """
101
101
 
102
102
class PackRootCommitBuilder(RootCommitBuilder):
103
103
    """A subclass of RootCommitBuilder to add texts with pack semantics.
104
 
    
 
104
 
105
105
    Specifically this uses one knit object rather than one knit object per
106
106
    added text, reducing memory and object pressure.
107
107
    """
274
274
            mutter('%s: create_pack: pack stream open: %s%s t+%6.3fs',
275
275
                time.ctime(), self.upload_transport.base, self.random_name,
276
276
                time.time() - self.start_time)
277
 
        # A list of byte sequences to be written to the new pack, and the 
278
 
        # aggregate size of them.  Stored as a list rather than separate 
 
277
        # A list of byte sequences to be written to the new pack, and the
 
278
        # aggregate size of them.  Stored as a list rather than separate
279
279
        # variables so that the _write_data closure below can update them.
280
280
        self._buffer = [[], 0]
281
 
        # create a callable for adding data 
 
281
        # create a callable for adding data
282
282
        #
283
283
        # robertc says- this is a closure rather than a method on the object
284
284
        # so that the variables are locals, and faster than accessing object
320
320
 
321
321
    def _check_references(self):
322
322
        """Make sure our external references are present.
323
 
        
 
323
 
324
324
        Packs are allowed to have deltas whose base is not in the pack, but it
325
325
        must be present somewhere in this collection.  It is not allowed to
326
 
        have deltas based on a fallback repository. 
 
326
        have deltas based on a fallback repository.
327
327
        (See <https://bugs.launchpad.net/bzr/+bug/288751>)
328
328
        """
329
329
        missing_items = {}
336
336
                self._pack_collection.inventory_index.combined_index),
337
337
            ]:
338
338
            missing = external_refs.difference(
339
 
                k for (idx, k, v, r) in 
 
339
                k for (idx, k, v, r) in
340
340
                index.iter_entries(external_refs))
341
341
            if missing:
342
342
                missing_items[index_name] = sorted(list(missing))
444
444
            mutter('%s: create_pack: wrote %s index: %s%s t+%6.3fs',
445
445
                time.ctime(), label, self.upload_transport.base,
446
446
                self.random_name, time.time() - self.start_time)
447
 
        # Replace the writable index on this object with a readonly, 
 
447
        # Replace the writable index on this object with a readonly,
448
448
        # presently unloaded index. We should alter
449
449
        # the index layer to make its finish() error if add_node is
450
450
        # subsequently used. RBC
459
459
    such as 'revision index'.
460
460
 
461
461
    A CombinedIndex provides an index on a single key space built up
462
 
    from several on-disk indices.  The AggregateIndex builds on this 
 
462
    from several on-disk indices.  The AggregateIndex builds on this
463
463
    to provide a knit access layer, and allows having up to one writable
464
464
    index within the collection.
465
465
    """
505
505
 
506
506
        Future searches on the aggregate index will seach this new index
507
507
        before all previously inserted indices.
508
 
        
 
508
 
509
509
        :param index: An Index for the pack.
510
510
        :param pack: A Pack instance.
511
511
        """
519
519
 
520
520
        There can be at most one writable index at any time.  Any
521
521
        modifications made to the knit are put into this index.
522
 
        
 
522
 
523
523
        :param index: An index from the pack parameter.
524
524
        :param pack: A Pack instance.
525
525
        """
542
542
 
543
543
    def remove_index(self, index, pack):
544
544
        """Remove index from the indices used to answer queries.
545
 
        
 
545
 
546
546
        :param index: An index from the pack parameter.
547
547
        :param pack: A Pack instance.
548
548
        """
623
623
        This does little more than a bulk copy of data. One key difference
624
624
        is that data with the same item key across multiple packs is elided
625
625
        from the output. The new pack is written into the current pack store
626
 
        along with its indices, and the name added to the pack names. The 
 
626
        along with its indices, and the name added to the pack names. The
627
627
        source packs are not altered and are not required to be in the current
628
628
        pack collection.
629
629
 
848
848
        nodes = sorted(nodes)
849
849
        # how to map this into knit.py - or knit.py into this?
850
850
        # we don't want the typical knit logic, we want grouping by pack
851
 
        # at this point - perhaps a helper library for the following code 
 
851
        # at this point - perhaps a helper library for the following code
852
852
        # duplication points?
853
853
        request_groups = {}
854
854
        for index, key, value in nodes:
954
954
 
955
955
    def _least_readv_node_readv(self, nodes):
956
956
        """Generate request groups for nodes using the least readv's.
957
 
        
 
957
 
958
958
        :param nodes: An iterable of graph index nodes.
959
959
        :return: Total node count and an iterator of the data needed to perform
960
960
            readvs to obtain the data for nodes. Each item yielded by the
1071
1071
 
1072
1072
class ReconcilePacker(Packer):
1073
1073
    """A packer which regenerates indices etc as it copies.
1074
 
    
 
1074
 
1075
1075
    This is used by ``bzr reconcile`` to cause parent text pointers to be
1076
1076
    regenerated.
1077
1077
    """
1100
1100
        # 1) generate the ideal index
1101
1101
        repo = self._pack_collection.repo
1102
1102
        ancestors = dict([(key[0], tuple(ref[0] for ref in refs[0])) for
1103
 
            _1, key, _2, refs in 
 
1103
            _1, key, _2, refs in
1104
1104
            self.new_pack.revision_index.iter_all_entries()])
1105
1105
        ideal_index = repo._generate_text_key_index(self._text_refs, ancestors)
1106
1106
        # 2) generate a text_nodes list that contains all the deltas that can
1112
1112
        text_index_map, text_nodes = self._get_text_nodes()
1113
1113
        for node in text_nodes:
1114
1114
            # 0 - index
1115
 
            # 1 - key 
 
1115
            # 1 - key
1116
1116
            # 2 - value
1117
1117
            # 3 - refs
1118
1118
            try:
1213
1213
 
1214
1214
class RepositoryPackCollection(object):
1215
1215
    """Management of packs within a repository.
1216
 
    
 
1216
 
1217
1217
    :ivar _names: map of {pack_name: (index_size,)}
1218
1218
    """
1219
1219
 
1221
1221
                 pack_transport, index_builder_class, index_class):
1222
1222
        """Create a new RepositoryPackCollection.
1223
1223
 
1224
 
        :param transport: Addresses the repository base directory 
 
1224
        :param transport: Addresses the repository base directory
1225
1225
            (typically .bzr/repository/).
1226
1226
        :param index_transport: Addresses the directory containing indices.
1227
1227
        :param upload_transport: Addresses the directory into which packs are written
1253
1253
 
1254
1254
    def add_pack_to_memory(self, pack):
1255
1255
        """Make a Pack object available to the repository to satisfy queries.
1256
 
        
 
1256
 
1257
1257
        :param pack: A Pack object.
1258
1258
        """
1259
1259
        if pack.name in self._packs_by_name:
1264
1264
        self.inventory_index.add_index(pack.inventory_index, pack)
1265
1265
        self.text_index.add_index(pack.text_index, pack)
1266
1266
        self.signature_index.add_index(pack.signature_index, pack)
1267
 
        
 
1267
 
1268
1268
    def all_packs(self):
1269
1269
        """Return a list of all the Pack objects this repository has.
1270
1270
 
1279
1279
 
1280
1280
    def autopack(self):
1281
1281
        """Pack the pack collection incrementally.
1282
 
        
 
1282
 
1283
1283
        This will not attempt global reorganisation or recompression,
1284
1284
        rather it will just ensure that the total number of packs does
1285
1285
        not grow without bound. It uses the _max_pack_count method to
1322
1322
                # group their data with the relevant commit, and that may
1323
1323
                # involve rewriting ancient history - which autopack tries to
1324
1324
                # avoid. Alternatively we could not group the data but treat
1325
 
                # each of these as having a single revision, and thus add 
 
1325
                # each of these as having a single revision, and thus add
1326
1326
                # one revision for each to the total revision count, to get
1327
1327
                # a matching distribution.
1328
1328
                continue
1375
1375
 
1376
1376
    def lock_names(self):
1377
1377
        """Acquire the mutex around the pack-names index.
1378
 
        
 
1378
 
1379
1379
        This cannot be used in the middle of a read-only transaction on the
1380
1380
        repository.
1381
1381
        """
1508
1508
 
1509
1509
    def _iter_disk_pack_index(self):
1510
1510
        """Iterate over the contents of the pack-names index.
1511
 
        
 
1511
 
1512
1512
        This is used when loading the list from disk, and before writing to
1513
1513
        detect updates from others during our write operation.
1514
1514
        :return: An iterator of the index contents.
1525
1525
 
1526
1526
    def _max_pack_count(self, total_revisions):
1527
1527
        """Return the maximum number of packs to use for total revisions.
1528
 
        
 
1528
 
1529
1529
        :param total_revisions: The total number of revisions in the
1530
1530
            repository.
1531
1531
        """
1586
1586
 
1587
1587
    def _remove_pack_from_memory(self, pack):
1588
1588
        """Remove pack from the packs accessed by this repository.
1589
 
        
 
1589
 
1590
1590
        Only affects memory state, until self._save_pack_names() is invoked.
1591
1591
        """
1592
1592
        self._names.pop(pack.name)
1717
1717
        try:
1718
1718
            builder = self._index_builder_class()
1719
1719
            disk_nodes, deleted_nodes, new_nodes = self._diff_pack_names()
1720
 
            # TODO: handle same-name, index-size-changes here - 
 
1720
            # TODO: handle same-name, index-size-changes here -
1721
1721
            # e.g. use the value from disk, not ours, *unless* we're the one
1722
1722
            # changing it.
1723
1723
            for key, value in disk_nodes:
1823
1823
 
1824
1824
class KnitPackRepository(KnitRepository):
1825
1825
    """Repository with knit objects stored inside pack containers.
1826
 
    
 
1826
 
1827
1827
    The layering for a KnitPackRepository is:
1828
1828
 
1829
1829
    Graph        |  HPSS    | Repository public layer |
1843
1843
      pack file. The GraphIndex layer works in N-tuples and is unaware of any
1844
1844
      semantic value.
1845
1845
    ===================================================
1846
 
    
 
1846
 
1847
1847
    """
1848
1848
 
1849
1849
    def __init__(self, _format, a_bzrdir, control_files, _commit_builder_class,
1882
1882
            data_access=self._pack_collection.text_index.data_access,
1883
1883
            max_delta_chain=200)
1884
1884
        # True when the repository object is 'write locked' (as opposed to the
1885
 
        # physical lock only taken out around changes to the pack-names list.) 
 
1885
        # physical lock only taken out around changes to the pack-names list.)
1886
1886
        # Another way to represent this would be a decorator around the control
1887
1887
        # files object that presents logical locks as physical ones - if this
1888
1888
        # gets ugly consider that alternative design. RBC 20071011
2097
2097
        builder = self.index_builder_class()
2098
2098
        files = [('pack-names', builder.finish())]
2099
2099
        utf8_files = [('format', self.get_format_string())]
2100
 
        
 
2100
 
2101
2101
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
2102
2102
        return self.open(a_bzrdir=a_bzrdir, _found=True)
2103
2103
 
2104
2104
    def open(self, a_bzrdir, _found=False, _override_transport=None):
2105
2105
        """See RepositoryFormat.open().
2106
 
        
 
2106
 
2107
2107
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
2108
2108
                                    repository at a slightly different url
2109
2109
                                    than normal. I.e. during 'upgrade'.
2195
2195
        if not getattr(target_format, 'supports_tree_reference', False):
2196
2196
            raise errors.BadConversionTarget(
2197
2197
                'Does not support nested trees', target_format)
2198
 
            
 
2198
 
2199
2199
    def get_format_string(self):
2200
2200
        """See RepositoryFormat.get_format_string()."""
2201
2201
        return "Bazaar pack repository format 1 with subtree support (needs bzr 0.92)\n"
2541
2541
        if not getattr(target_format, 'supports_tree_reference', False):
2542
2542
            raise errors.BadConversionTarget(
2543
2543
                'Does not support nested trees', target_format)
2544
 
            
 
2544
 
2545
2545
    def get_format_string(self):
2546
2546
        """See RepositoryFormat.get_format_string()."""
2547
2547
        return ("Bazaar development format 2 with subtree support "