314
309
def finish(self):
315
310
self._check_references()
316
new_name = '../packs/' + self.file_name()
317
self.upload_transport.rename(self.file_name(), new_name)
318
311
index_types = ['revision', 'inventory', 'text', 'signature']
319
312
if self.chk_index is not None:
320
313
index_types.append('chk')
323
316
new_name = '../indices/' + old_name
324
317
self.upload_transport.rename(old_name, new_name)
325
318
self._replace_index_with_readonly(index_type)
319
new_name = '../packs/' + self.file_name()
320
self.upload_transport.rename(self.file_name(), new_name)
326
321
self._state = 'finished'
328
323
def _get_external_refs(self, index):
1459
1454
in synchronisation with certain steps. Otherwise the names collection
1460
1455
is not flushed.
1462
:return: True if packing took place.
1457
:return: Something evaluating true if packing took place.
1466
1461
return self._do_autopack()
1467
except errors.RetryAutopack, e:
1462
except errors.RetryAutopack:
1468
1463
# If we get a RetryAutopack exception, we should abort the
1469
1464
# current action, and retry.
1474
1469
total_revisions = self.revision_index.combined_index.key_count()
1475
1470
total_packs = len(self._names)
1476
1471
if self._max_pack_count(total_revisions) >= total_packs:
1478
1473
# determine which packs need changing
1479
1474
pack_distribution = self.pack_distribution(total_revisions)
1480
1475
existing_packs = []
1502
1497
'containing %d revisions. Packing %d files into %d affecting %d'
1503
1498
' revisions', self, total_packs, total_revisions, num_old_packs,
1504
1499
num_new_packs, num_revs_affected)
1505
self._execute_pack_operations(pack_operations,
1500
result = self._execute_pack_operations(pack_operations,
1506
1501
reload_func=self._restart_autopack)
1507
1502
mutter('Auto-packing repository %s completed', self)
1510
1505
def _execute_pack_operations(self, pack_operations, _packer_class=Packer,
1511
1506
reload_func=None):
1514
1509
:param pack_operations: A list of [revision_count, packs_to_combine].
1515
1510
:param _packer_class: The class of packer to use (default: Packer).
1511
:return: The new pack names.
1518
1513
for revision_count, packs in pack_operations:
1519
1514
# we may have no-ops from the setup logic
1535
1530
self._remove_pack_from_memory(pack)
1536
1531
# record the newly available packs and stop advertising the old
1538
self._save_pack_names(clear_obsolete_packs=True)
1533
result = self._save_pack_names(clear_obsolete_packs=True)
1539
1534
# Move the old packs out of the way now they are no longer referenced.
1540
1535
for revision_count, packs in pack_operations:
1541
1536
self._obsolete_packs(packs)
1543
1539
def _flush_new_pack(self):
1544
1540
if self._new_pack is not None:
1555
1551
def _already_packed(self):
1556
1552
"""Is the collection already packed?"""
1557
return len(self._names) < 2
1553
return not (self.repo._format.pack_compresses or (len(self._names) > 1))
1555
def pack(self, hint=None):
1560
1556
"""Pack the pack collection totally."""
1561
1557
self.ensure_loaded()
1562
1558
total_packs = len(self._names)
1563
1559
if self._already_packed():
1564
# This is arguably wrong because we might not be optimal, but for
1565
# now lets leave it in. (e.g. reconcile -> one pack. But not
1568
1561
total_revisions = self.revision_index.combined_index.key_count()
1569
1562
# XXX: the following may want to be a class, to pack with a given
1571
1564
mutter('Packing repository %s, which has %d pack files, '
1572
'containing %d revisions into 1 packs.', self, total_packs,
1565
'containing %d revisions with hint %r.', self, total_packs,
1566
total_revisions, hint)
1574
1567
# determine which packs need changing
1575
pack_distribution = [1]
1576
1568
pack_operations = [[0, []]]
1577
1569
for pack in self.all_packs():
1578
pack_operations[-1][0] += pack.get_revision_count()
1579
pack_operations[-1][1].append(pack)
1570
if not hint or pack.name in hint:
1571
pack_operations[-1][0] += pack.get_revision_count()
1572
pack_operations[-1][1].append(pack)
1580
1573
self._execute_pack_operations(pack_operations, OptimisingPacker)
1582
1575
def plan_autopack_combinations(self, existing_packs, pack_distribution):
1958
1952
self._unlock_names()
1959
1953
# synchronise the memory packs list with what we just wrote:
1960
1954
self._syncronize_pack_names_from_disk_nodes(disk_nodes)
1955
return [new_node[0][0] for new_node in new_nodes]
1962
1957
def reload_pack_names(self):
1963
1958
"""Sync our pack listing with what is present in the repository.
2097
2092
if not self.autopack():
2098
2093
# when autopack takes no steps, the names list is still
2100
self._save_pack_names()
2095
return self._save_pack_names()
2102
2097
def _suspend_write_group(self):
2103
2098
tokens = [pack.name for pack in self._resumed_packs]
2348
2343
raise NotImplementedError(self.dont_leave_lock_in_place)
2350
2345
@needs_write_lock
2346
def pack(self, hint=None):
2352
2347
"""Compress the data within the repository.
2354
2349
This will pack all the data to a single pack. In future it may
2355
2350
recompress deltas or do other such expensive operations.
2357
self._pack_collection.pack()
2352
self._pack_collection.pack(hint=hint)
2359
2354
@needs_write_lock
2360
2355
def reconcile(self, other=None, thorough=False):