56
56
from bzrlib.decorators import needs_write_lock
57
from bzrlib.btree_index import (
61
from bzrlib.index import (
57
65
from bzrlib.repofmt.knitrepo import KnitRepository
58
66
from bzrlib.repository import (
217
225
def __init__(self, upload_transport, index_transport, pack_transport,
218
upload_suffix='', file_mode=None):
226
upload_suffix='', file_mode=None, index_builder_class=None,
219
228
"""Create a NewPack instance.
221
230
:param upload_transport: A writable transport for the pack to be
228
237
:param upload_suffix: An optional suffix to be given to any temporary
229
238
files created during the pack creation. e.g '.autopack'
230
239
:param file_mode: An optional file mode to create the new files with.
240
:param index_builder_class: Required keyword parameter - the class of
241
index builder to use.
242
:param index_class: Required keyword parameter - the class of index
232
245
# The relative locations of the packs are constrained, but all are
233
246
# passed in because the caller has them, so as to avoid object churn.
234
247
Pack.__init__(self,
235
248
# Revisions: parents list, no text compression.
236
InMemoryGraphIndex(reference_lists=1),
249
index_builder_class(reference_lists=1),
237
250
# Inventory: We want to map compression only, but currently the
238
251
# knit code hasn't been updated enough to understand that, so we
239
252
# have a regular 2-list index giving parents and compression
241
InMemoryGraphIndex(reference_lists=2),
254
index_builder_class(reference_lists=2),
242
255
# Texts: compression and per file graph, for all fileids - so two
243
256
# reference lists and two elements in the key tuple.
244
InMemoryGraphIndex(reference_lists=2, key_elements=2),
257
index_builder_class(reference_lists=2, key_elements=2),
245
258
# Signatures: Just blobs to store, no compression, no parents
247
InMemoryGraphIndex(reference_lists=0),
260
index_builder_class(reference_lists=0),
262
# When we make readonly indices, we need this.
263
self.index_class = index_class
249
264
# where should the new pack be opened
250
265
self.upload_transport = upload_transport
251
266
# where are indices written out to
393
408
def _replace_index_with_readonly(self, index_type):
394
409
setattr(self, index_type + '_index',
395
GraphIndex(self.index_transport,
410
self.index_class(self.index_transport,
396
411
self.index_name(index_type, self.name),
397
412
self.index_sizes[self.index_offset(index_type)]))
591
606
return NewPack(self._pack_collection._upload_transport,
592
607
self._pack_collection._index_transport,
593
608
self._pack_collection._pack_transport, upload_suffix=self.suffix,
594
file_mode=self._pack_collection.repo.bzrdir._get_file_mode())
609
file_mode=self._pack_collection.repo.bzrdir._get_file_mode(),
610
index_builder_class=self._pack_collection._index_builder_class,
611
index_class=self._pack_collection._index_class)
596
613
def _copy_revision_texts(self):
597
614
"""Copy revision data to the new pack."""
1106
1123
def __init__(self, repo, transport, index_transport, upload_transport,
1124
pack_transport, index_builder_class, index_class):
1108
1125
"""Create a new RepositoryPackCollection.
1110
1127
:param transport: Addresses the repository base directory
1113
1130
:param upload_transport: Addresses the directory into which packs are written
1114
1131
while they're being created.
1115
1132
:param pack_transport: Addresses the directory of existing complete packs.
1133
:param index_builder_class: The index builder class to use.
1134
:param index_class: The index class to use.
1117
1136
self.repo = repo
1118
1137
self.transport = transport
1119
1138
self._index_transport = index_transport
1120
1139
self._upload_transport = upload_transport
1121
1140
self._pack_transport = pack_transport
1141
self._index_builder_class = index_builder_class
1142
self._index_class = index_class
1122
1143
self._suffix_offsets = {'.rix': 0, '.iix': 1, '.tix': 2, '.six': 3}
1123
1144
self.packs = []
1124
1145
# name:Pack mapping
1275
1296
# plan out what packs to keep, and what to reorganise
1276
1297
while len(existing_packs):
1277
1298
# take the largest pack, and if its less than the head of the
1278
# distribution chart we will include its contents in the new pack for
1279
# that position. If its larger, we remove its size from the
1299
# distribution chart we will include its contents in the new pack
1300
# for that position. If its larger, we remove its size from the
1280
1301
# distribution chart
1281
1302
next_pack_rev_count, next_pack = existing_packs.pop(0)
1282
1303
if next_pack_rev_count >= pack_distribution[0]:
1299
1320
# this pack is used up, shift left.
1300
1321
del pack_distribution[0]
1301
1322
pack_operations.append([0, []])
1303
return pack_operations
1323
# Now that we know which pack files we want to move, shove them all
1324
# into a single pack file.
1326
final_pack_list = []
1327
for num_revs, pack_files in pack_operations:
1328
final_rev_count += num_revs
1329
final_pack_list.extend(pack_files)
1330
if len(final_pack_list) == 1:
1331
raise AssertionError('We somehow generated an autopack with a'
1332
' single pack file being moved.')
1334
return [[final_rev_count, final_pack_list]]
1305
1336
def ensure_loaded(self):
1306
1337
# NB: if you see an assertion error here, its probably access against
1359
1390
detect updates from others during our write operation.
1360
1391
:return: An iterator of the index contents.
1362
return GraphIndex(self.transport, 'pack-names', None
1393
return self._index_class(self.transport, 'pack-names', None
1363
1394
).iter_all_entries()
1365
1396
def _make_index(self, name, suffix):
1366
1397
size_offset = self._suffix_offsets[suffix]
1367
1398
index_name = name + suffix
1368
1399
index_size = self._names[name][size_offset]
1400
return self._index_class(
1370
1401
self._index_transport, index_name, index_size)
1372
1403
def _max_pack_count(self, total_revisions):
1536
1567
self.lock_names()
1538
builder = GraphIndexBuilder()
1569
builder = self._index_builder_class()
1539
1570
# load the disk nodes across
1540
1571
disk_nodes = set()
1541
1572
for index, key, value in self._iter_disk_pack_index():
1607
1638
raise errors.NotWriteLocked(self)
1608
1639
self._new_pack = NewPack(self._upload_transport, self._index_transport,
1609
1640
self._pack_transport, upload_suffix='.pack',
1610
file_mode=self.repo.bzrdir._get_file_mode())
1641
file_mode=self.repo.bzrdir._get_file_mode(),
1642
index_builder_class=self._index_builder_class,
1643
index_class=self._index_class)
1611
1644
# allow writing: queue writes to a new index
1612
1645
self.revision_index.add_writable_index(self._new_pack.revision_index,
1613
1646
self._new_pack)
1682
1715
self._pack_collection = RepositoryPackCollection(self, self._transport,
1683
1716
index_transport,
1684
1717
self._transport.clone('upload'),
1685
self._transport.clone('packs'))
1718
self._transport.clone('packs'),
1719
_format.index_builder_class,
1720
_format.index_class)
1686
1721
self.inventories = KnitVersionedFiles(
1687
1722
_KnitGraphIndex(self._pack_collection.inventory_index.combined_index,
1688
1723
add_callback=self._pack_collection.inventory_index.add_callback,
1906
1941
_serializer = None
1907
1942
# External references are not supported in pack repositories yet.
1908
1943
supports_external_lookups = False
1944
# What index classes to use
1945
index_builder_class = None
1910
1948
def initialize(self, a_bzrdir, shared=False):
1911
1949
"""Create a pack based repository.
1918
1956
mutter('creating repository in %s.', a_bzrdir.transport.base)
1919
1957
dirs = ['indices', 'obsolete_packs', 'packs', 'upload']
1920
builder = GraphIndexBuilder()
1958
builder = self.index_builder_class()
1921
1959
files = [('pack-names', builder.finish())]
1922
1960
utf8_files = [('format', self.get_format_string())]
1955
1993
repository_class = KnitPackRepository
1956
1994
_commit_builder_class = PackCommitBuilder
1957
1995
_serializer = xml5.serializer_v5
1996
# What index classes to use
1997
index_builder_class = InMemoryGraphIndex
1998
index_class = GraphIndex
1959
2000
def _get_matching_bzrdir(self):
1960
2001
return bzrdir.format_registry.make_bzrdir('pack-0.92')
1991
2032
rich_root_data = True
1992
2033
supports_tree_reference = True
1993
2034
_serializer = xml7.serializer_v7
2035
# What index classes to use
2036
index_builder_class = InMemoryGraphIndex
2037
index_class = GraphIndex
1995
2039
def _get_matching_bzrdir(self):
1996
2040
return bzrdir.format_registry.make_bzrdir(
2032
2076
rich_root_data = True
2033
2077
supports_tree_reference = False
2034
2078
_serializer = xml6.serializer_v6
2079
# What index classes to use
2080
index_builder_class = InMemoryGraphIndex
2081
index_class = GraphIndex
2036
2083
def _get_matching_bzrdir(self):
2037
2084
return bzrdir.format_registry.make_bzrdir(
2070
2117
_commit_builder_class = PackCommitBuilder
2071
2118
_serializer = xml5.serializer_v5
2072
2119
supports_external_lookups = True
2120
# What index classes to use
2121
index_builder_class = InMemoryGraphIndex
2122
index_class = GraphIndex
2074
2124
def _get_matching_bzrdir(self):
2075
return bzrdir.format_registry.make_bzrdir('development1')
2125
return bzrdir.format_registry.make_bzrdir('1.6')
2077
2127
def _ignore_setting_bzrdir(self, format):
2106
2156
supports_tree_reference = False # no subtrees
2107
2157
_serializer = xml6.serializer_v6
2108
2158
supports_external_lookups = True
2159
# What index classes to use
2160
index_builder_class = InMemoryGraphIndex
2161
index_class = GraphIndex
2110
2163
def _get_matching_bzrdir(self):
2111
2164
return bzrdir.format_registry.make_bzrdir(
2149
2202
_serializer = xml7.serializer_v7
2151
2204
supports_external_lookups = True
2205
# What index classes to use
2206
index_builder_class = InMemoryGraphIndex
2207
index_class = GraphIndex
2153
2209
def _get_matching_bzrdir(self):
2154
2210
return bzrdir.format_registry.make_bzrdir(
2155
'development1-subtree')
2157
2213
def _ignore_setting_bzrdir(self, format):
2173
2229
" (deprecated)")
2176
class RepositoryFormatPackDevelopment1(RepositoryFormatPack):
2232
class RepositoryFormatPackDevelopment2(RepositoryFormatPack):
2177
2233
"""A no-subtrees development repository.
2179
This format should be retained until the second release after bzr 1.5.
2235
This format should be retained until the second release after bzr 1.7.
2181
Supports external lookups, which results in non-truncated ghosts after
2182
reconcile compared to pack-0.92 formats.
2237
This is pack-1.6.1 with B+Tree indices.
2185
2240
repository_class = KnitPackRepository
2186
2241
_commit_builder_class = PackCommitBuilder
2187
2242
_serializer = xml5.serializer_v5
2188
2243
supports_external_lookups = True
2244
# What index classes to use
2245
index_builder_class = BTreeBuilder
2246
index_class = BTreeGraphIndex
2190
2248
def _get_matching_bzrdir(self):
2191
return bzrdir.format_registry.make_bzrdir('development1')
2249
return bzrdir.format_registry.make_bzrdir('development2')
2193
2251
def _ignore_setting_bzrdir(self, format):
2198
2256
def get_format_string(self):
2199
2257
"""See RepositoryFormat.get_format_string()."""
2200
return "Bazaar development format 1 (needs bzr.dev from before 1.6)\n"
2258
return "Bazaar development format 2 (needs bzr.dev from before 1.8)\n"
2202
2260
def get_format_description(self):
2203
2261
"""See RepositoryFormat.get_format_description()."""
2204
2262
return ("Development repository format, currently the same as "
2205
"pack-0.92 with external reference support.\n")
2263
"1.6.1 with B+Trees.\n")
2207
2265
def check_conversion_target(self, target_format):
2211
class RepositoryFormatPackDevelopment1Subtree(RepositoryFormatPack):
2269
class RepositoryFormatPackDevelopment2Subtree(RepositoryFormatPack):
2212
2270
"""A subtrees development repository.
2214
This format should be retained until the second release after bzr 1.5.
2272
This format should be retained until the second release after bzr 1.7.
2216
Supports external lookups, which results in non-truncated ghosts after
2217
reconcile compared to pack-0.92 formats.
2274
1.6.1-subtree[as it might have been] with B+Tree indices.
2220
2277
repository_class = KnitPackRepository
2223
2280
supports_tree_reference = True
2224
2281
_serializer = xml7.serializer_v7
2225
2282
supports_external_lookups = True
2283
# What index classes to use
2284
index_builder_class = BTreeBuilder
2285
index_class = BTreeGraphIndex
2227
2287
def _get_matching_bzrdir(self):
2228
2288
return bzrdir.format_registry.make_bzrdir(
2229
'development1-subtree')
2289
'development2-subtree')
2231
2291
def _ignore_setting_bzrdir(self, format):
2244
2304
def get_format_string(self):
2245
2305
"""See RepositoryFormat.get_format_string()."""
2246
return ("Bazaar development format 1 with subtree support "
2247
"(needs bzr.dev from before 1.6)\n")
2306
return ("Bazaar development format 2 with subtree support "
2307
"(needs bzr.dev from before 1.8)\n")
2249
2309
def get_format_description(self):
2250
2310
"""See RepositoryFormat.get_format_description()."""
2251
2311
return ("Development repository format, currently the same as "
2252
"pack-0.92-subtree with external reference support.\n")
2312
"1.6.1-subtree with B+Tree indices.\n")