98
98
ExistingPack and NewPack are used.
101
def __init__(self, revision_index, inventory_index):
101
def __init__(self, revision_index, inventory_index, text_index):
102
102
"""Create a pack instance.
104
104
:param revision_index: A GraphIndex for determining what revisions are
105
105
present in the Pack and accessing the locations of their texts.
106
106
:param inventory_index: A GraphIndex for determining what inventories are
107
present in the Pack and accessing the locations of their texts.
107
present in the Pack and accessing the locations of their
109
:param text_index: A GraphIndex for determining what file texts
110
are present in the pack and accessing the locations of their
111
texts/deltas (via (fileid, revisionid) tuples).
109
113
self.revision_index = revision_index
110
114
self.inventory_index = inventory_index
115
self.text_index = text_index
112
117
def get_revision_count(self):
113
118
return self.revision_index.key_count()
135
140
def __init__(self, transport, name, revision_index, inventory_index,
136
141
text_index, signature_index):
137
Pack.__init__(self, revision_index, inventory_index)
142
Pack.__init__(self, revision_index, inventory_index, text_index)
138
143
self.text_index = text_index
139
144
self.signature_index = signature_index
180
185
# knit code hasn't been updated enough to understand that, so we
181
186
# have a regular 2-list index giving parents and compression
183
InMemoryGraphIndex(reference_lists=2))
188
InMemoryGraphIndex(reference_lists=2),
189
# Texts: compression and per file graph, for all fileids - so two
190
# reference lists and two elements in the key tuple.
191
InMemoryGraphIndex(reference_lists=2, key_elements=2),
184
193
# where should the new pack be opened
185
194
self.upload_transport = upload_transport
186
195
# where are indices written out to
211
220
new_name = self._hash.hexdigest()
212
221
self.index_sizes = [None, None, None, None]
214
revision_index_name = self.revision_index_name(new_name)
215
self.index_sizes[0] = self.index_transport.put_file(
216
revision_index_name, self.revision_index.finish())
217
if 'fetch' in debug.debug_flags:
218
# XXX: size might be interesting?
219
mutter('%s: create_pack: wrote revision index: %s%s t+%6.3fs',
220
time.ctime(), self.upload_transport.base, self.random_name,
221
time.time() - self.start_time)
223
inv_index_name = self.inventory_index_name(new_name)
224
self.index_sizes[1] = self.index_transport.put_file(inv_index_name,
225
self.inventory_index.finish())
226
if 'fetch' in debug.debug_flags:
227
# XXX: size might be interesting?
228
mutter('%s: create_pack: wrote inventory index: %s%s t+%6.3fs',
229
time.ctime(), self.upload_transport.base, self.random_name,
230
time.time() - self.start_time)
222
self._write_index(new_name, self.revision_index, 0,
223
self.revision_index_name, 'revision')
224
self._write_index(new_name, self.inventory_index, 1,
225
self.inventory_index_name, 'inventory')
226
self._write_index(new_name, self.text_index, 2,
227
self.text_index_name, 'file texts')
229
def _write_index(self, new_name, index, index_offset, name_getter, label):
230
"""Write out an index.
232
:param new_name: The basename of the pack.
233
:param index: The index object to serialise.
234
:param index_offset: Where in self.index_sizes to remember this.
235
:param name_getter: What to use to get the name of the index on disk.
236
:param label: What label to give the index e.g. 'revision'.
238
index_name = name_getter(new_name)
239
self.index_sizes[index_offset] = self.index_transport.put_file(
240
index_name, index.finish())
241
if 'fetch' in debug.debug_flags:
242
# XXX: size might be interesting?
243
mutter('%s: create_pack: wrote %s index: %s%s t+%6.3fs',
244
time.ctime(), label, self.upload_transport.base,
245
self.random_name, time.time() - self.start_time)
233
248
class RepositoryPackCollection(object):
293
308
file_id_index = GraphIndexPrefixAdapter(
294
309
self.repo._text_all_indices,
296
add_nodes_callback=self.repo._text_write_index.add_nodes)
311
add_nodes_callback=self.repo._packs._new_pack.text_index.add_nodes)
297
312
self.repo._text_knit._index._graph_index = file_id_index
298
313
self.repo._text_knit._index._add_callback = file_id_index.add_nodes
299
314
return self.repo._text_knit.add_lines_with_ghosts(
422
437
self.repo._inv_pack_map = None
425
def flush_text_index(self, new_name):
440
def flush_text_index(self, new_name, text_index_length):
426
441
"""Write the index out to new_name."""
427
442
# write a revision index (might be empty)
428
443
new_index_name = self._new_pack.text_index_name(new_name)
429
text_index_length = self._index_transport.put_file(
430
new_index_name, self.repo._text_write_index.finish())
431
444
txt_index = GraphIndex(self._index_transport, new_index_name,
432
445
text_index_length)
433
self.repo._text_write_index = None
434
446
self.repo.weave_store._setup_knit(False)
435
447
if self.repo._text_all_indices is not None:
436
448
# text 'knits' have been used, replace the mutated memory index
440
452
# remove the write buffering index. XXX: API break
441
453
# - clearly we need a remove_index call too.
442
454
del self.repo._text_all_indices._indices[1]
443
return txt_index, text_index_length
445
457
def create_pack_from_packs(self, packs, suffix, revision_ids=None):
446
458
"""Create a new pack by reading data from other packs.
572
583
a_missing_key[0])
573
584
# copy text keys and adjust values
574
585
list(self._copy_nodes_graph(text_nodes, text_index_map, writer,
586
new_pack.text_index))
576
587
if 'fetch' in debug.debug_flags:
577
588
mutter('%s: create_pack: file texts copied: %s%s %d items t+%6.3fs',
578
589
time.ctime(), self._upload_transport.base, random_name,
579
text_index.key_count(),
590
new_pack.text_index.key_count(),
580
591
time.time() - new_pack.start_time)
581
592
# select signature keys
582
593
signature_filter = revision_keys # same keyspace
601
612
# if nothing has been written, discard the new pack.
602
613
if 0 == sum((new_pack.get_revision_count(),
603
614
new_pack.inventory_index.key_count(),
604
text_index.key_count(),
615
new_pack.text_index.key_count(),
605
616
signature_index.key_count(),
607
618
self._upload_transport.delete(random_name)
611
622
new_pack.finish()
612
623
revision_index_length = new_pack.index_sizes[0]
613
624
inventory_index_length = new_pack.index_sizes[1]
625
text_index_length = new_pack.index_sizes[2]
615
text_index_name = new_pack.text_index_name(new_name)
616
text_index_length = index_transport.put_file(text_index_name,
618
if 'fetch' in debug.debug_flags:
619
# XXX: size might be interesting?
620
mutter('%s: create_pack: wrote file texts index: %s%s t+%6.3fs',
621
time.ctime(), self._upload_transport.base, random_name,
622
time.time() - new_pack.start_time)
623
627
signature_index_name = new_pack.signature_index_name(new_name)
624
628
signature_index_length = index_transport.put_file(signature_index_name,
625
629
signature_index.finish())
636
640
write_stream.close()
637
641
self._upload_transport.rename(random_name, '../packs/' + new_name + '.pack')
638
642
result = ExistingPack(self._upload_transport.clone('../packs/'), new_name,
639
new_pack.revision_index, new_pack.inventory_index, text_index,
643
new_pack.revision_index, new_pack.inventory_index, new_pack.text_index,
641
645
if 'fetch' in debug.debug_flags:
642
646
# XXX: size might be interesting?
1156
1159
# its a deliberate attack or data corruption has
1157
1160
# occuring during the write of that file.
1158
1161
self.allocate(new_name, self._new_pack.index_sizes[0],
1159
self._new_pack.index_sizes[1], text_index_length,
1162
self._new_pack.index_sizes[1], self._new_pack.index_sizes[2],
1160
1163
signature_index_length)
1161
1164
self.repo._open_pack_tuple = None
1162
1165
self._new_pack = None
1313
1316
self._transport = weavestore._transport
1315
1318
def data_inserted(self):
1316
# XXX: Should we define __len__ for indices?
1317
if (getattr(self.repo, '_text_write_index', None) and
1318
self.repo._text_write_index.key_count()):
1319
if (self.repo._packs._new_pack is not None and
1320
self.repo._packs._new_pack.text_index.key_count()):
1321
1323
def _ensure_all_index(self, for_write=None):
1326
1328
self.repo._text_pack_map = pack_map
1327
1329
if for_write or self.repo.is_in_write_group():
1328
1330
# allow writing: queue writes to a new index
1329
indices.insert(0, self.repo._text_write_index)
1331
indices.insert(0, self.repo._packs._new_pack.text_index)
1330
1332
self._setup_knit(self.repo.is_in_write_group())
1331
1333
self.repo._text_all_indices = CombinedGraphIndex(indices)