587
586
flush_func=flush_func)
588
587
self.add_callback = None
589
def replace_indices(self, index_to_pack, indices):
590
"""Replace the current mappings with fresh ones.
592
This should probably not be used eventually, rather incremental add and
593
removal of indices. It has been added during refactoring of existing
596
:param index_to_pack: A mapping from index objects to
597
(transport, name) tuples for the pack file data.
598
:param indices: A list of indices.
600
# refresh the revision pack map dict without replacing the instance.
601
self.index_to_pack.clear()
602
self.index_to_pack.update(index_to_pack)
603
# XXX: API break - clearly a 'replace' method would be good?
604
self.combined_index._indices[:] = indices
605
# the current add nodes callback for the current writable index if
607
self.add_callback = None
590
609
def add_index(self, index, pack):
591
610
"""Add index to the aggregate, which is an index for Pack pack.
599
618
# expose it to the index map
600
619
self.index_to_pack[index] = pack.access_tuple()
601
620
# put it at the front of the linear index list
602
self.combined_index.insert_index(0, index, pack.name)
621
self.combined_index.insert_index(0, index)
604
623
def add_writable_index(self, index, pack):
605
624
"""Add an index which is able to have data added to it.
625
644
self.data_access.set_writer(None, None, (None, None))
626
645
self.index_to_pack.clear()
627
646
del self.combined_index._indices[:]
628
del self.combined_index._index_names[:]
629
647
self.add_callback = None
631
def remove_index(self, index):
649
def remove_index(self, index, pack):
632
650
"""Remove index from the indices used to answer queries.
634
652
:param index: An index from the pack parameter.
653
:param pack: A Pack instance.
636
655
del self.index_to_pack[index]
637
pos = self.combined_index._indices.index(index)
638
del self.combined_index._indices[pos]
639
del self.combined_index._index_names[pos]
656
self.combined_index._indices.remove(index)
640
657
if (self.add_callback is not None and
641
658
getattr(index, 'add_nodes', None) == self.add_callback):
642
659
self.add_callback = None
1398
1415
self.inventory_index = AggregateIndex(self.reload_pack_names, flush)
1399
1416
self.text_index = AggregateIndex(self.reload_pack_names, flush)
1400
1417
self.signature_index = AggregateIndex(self.reload_pack_names, flush)
1401
all_indices = [self.revision_index, self.inventory_index,
1402
self.text_index, self.signature_index]
1403
1418
if use_chk_index:
1404
1419
self.chk_index = AggregateIndex(self.reload_pack_names, flush)
1405
all_indices.append(self.chk_index)
1407
1421
# used to determine if we're using a chk_index elsewhere.
1408
1422
self.chk_index = None
1409
# Tell all the CombinedGraphIndex objects about each other, so they can
1410
# share hints about which pack names to search first.
1411
all_combined = [agg_idx.combined_index for agg_idx in all_indices]
1412
for combined_idx in all_combined:
1413
combined_idx.set_sibling_indices(
1414
set(all_combined).difference([combined_idx]))
1415
1423
# resumed packs
1416
1424
self._resumed_packs = []
1560
1568
"""Is the collection already packed?"""
1561
1569
return not (self.repo._format.pack_compresses or (len(self._names) > 1))
1563
def pack(self, hint=None, clean_obsolete_packs=False):
1571
def pack(self, hint=None):
1564
1572
"""Pack the pack collection totally."""
1565
1573
self.ensure_loaded()
1566
1574
total_packs = len(self._names)
1582
1590
pack_operations[-1][1].append(pack)
1583
1591
self._execute_pack_operations(pack_operations, OptimisingPacker)
1585
if clean_obsolete_packs:
1586
self._clear_obsolete_packs()
1588
1593
def plan_autopack_combinations(self, existing_packs, pack_distribution):
1589
1594
"""Plan a pack operation.
1835
1840
self._remove_pack_indices(pack)
1836
1841
self.packs.remove(pack)
1838
def _remove_pack_indices(self, pack, ignore_missing=False):
1839
"""Remove the indices for pack from the aggregated indices.
1841
:param ignore_missing: Suppress KeyErrors from calling remove_index.
1843
for index_type in Pack.index_definitions.keys():
1844
attr_name = index_type + '_index'
1845
aggregate_index = getattr(self, attr_name)
1846
if aggregate_index is not None:
1847
pack_index = getattr(pack, attr_name)
1849
aggregate_index.remove_index(pack_index)
1843
def _remove_pack_indices(self, pack):
1844
"""Remove the indices for pack from the aggregated indices."""
1845
self.revision_index.remove_index(pack.revision_index, pack)
1846
self.inventory_index.remove_index(pack.inventory_index, pack)
1847
self.text_index.remove_index(pack.text_index, pack)
1848
self.signature_index.remove_index(pack.signature_index, pack)
1849
if self.chk_index is not None:
1850
self.chk_index.remove_index(pack.chk_index, pack)
1855
1852
def reset(self):
1856
1853
"""Clear all cached data."""
2094
2091
# FIXME: just drop the transient index.
2095
2092
# forget what names there are
2096
2093
if self._new_pack is not None:
2097
operation = cleanup.OperationWithCleanups(self._new_pack.abort)
2098
operation.add_cleanup(setattr, self, '_new_pack', None)
2099
# If we aborted while in the middle of finishing the write
2100
# group, _remove_pack_indices could fail because the indexes are
2101
# already gone. But they're not there we shouldn't fail in this
2102
# case, so we pass ignore_missing=True.
2103
operation.add_cleanup(self._remove_pack_indices, self._new_pack,
2104
ignore_missing=True)
2105
operation.run_simple()
2095
self._new_pack.abort()
2097
# XXX: If we aborted while in the middle of finishing the write
2098
# group, _remove_pack_indices can fail because the indexes are
2099
# already gone. If they're not there we shouldn't fail in this
2100
# case. -- mbp 20081113
2101
self._remove_pack_indices(self._new_pack)
2102
self._new_pack = None
2106
2103
for resumed_pack in self._resumed_packs:
2107
operation = cleanup.OperationWithCleanups(resumed_pack.abort)
2108
# See comment in previous finally block.
2109
operation.add_cleanup(self._remove_pack_indices, resumed_pack,
2110
ignore_missing=True)
2111
operation.run_simple()
2105
resumed_pack.abort()
2107
# See comment in previous finally block.
2109
self._remove_pack_indices(resumed_pack)
2112
2112
del self._resumed_packs[:]
2114
2114
def _remove_resumed_pack_indices(self):
2378
2378
raise NotImplementedError(self.dont_leave_lock_in_place)
2380
2380
@needs_write_lock
2381
def pack(self, hint=None, clean_obsolete_packs=False):
2381
def pack(self, hint=None):
2382
2382
"""Compress the data within the repository.
2384
2384
This will pack all the data to a single pack. In future it may
2385
2385
recompress deltas or do other such expensive operations.
2387
self._pack_collection.pack(hint=hint, clean_obsolete_packs=clean_obsolete_packs)
2387
self._pack_collection.pack(hint=hint)
2389
2389
@needs_write_lock
2390
2390
def reconcile(self, other=None, thorough=False):
2546
2546
utf8_files = [('format', self.get_format_string())]
2548
2548
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
2549
repository = self.open(a_bzrdir=a_bzrdir, _found=True)
2550
self._run_post_repo_init_hooks(repository, a_bzrdir, shared)
2549
return self.open(a_bzrdir=a_bzrdir, _found=True)
2553
2551
def open(self, a_bzrdir, _found=False, _override_transport=None):
2554
2552
"""See RepositoryFormat.open().