457
457
# There are code paths that first extract as fulltext, and then
458
458
# extract as storage_kind (smart fetch). So we don't break the
459
459
# refcycle here, but instead in manager.get_record_stream()
460
# self._manager = None
461
460
if storage_kind == 'fulltext':
462
461
return self._bytes
546
545
# time (self._block._content) is a little expensive.
547
546
self._block._ensure_content(self._last_byte)
549
def _check_rebuild_block(self):
548
def _check_rebuild_action(self):
550
549
"""Check to see if our block should be repacked."""
551
550
total_bytes_used = 0
552
551
last_byte_used = 0
553
552
for factory in self._factories:
554
553
total_bytes_used += factory._end - factory._start
555
last_byte_used = max(last_byte_used, factory._end)
556
# If we are using most of the bytes from the block, we have nothing
557
# else to check (currently more than 1/2)
554
if last_byte_used < factory._end:
555
last_byte_used = factory._end
556
# If we are using more than half of the bytes from the block, we have
557
# nothing else to check
558
558
if total_bytes_used * 2 >= self._block._content_length:
560
# Can we just strip off the trailing bytes? If we are going to be
561
# transmitting more than 50% of the front of the content, go ahead
559
return None, last_byte_used
560
# We are using less than 50% of the content. Is the content we are
561
# using at the beginning of the block? If so, we can just trim the
562
# tail, rather than rebuilding from scratch.
562
563
if total_bytes_used * 2 > last_byte_used:
563
self._trim_block(last_byte_used)
564
return 'trim', last_byte_used
566
566
# We are using a small amount of the data, and it isn't just packed
567
567
# nicely at the front, so rebuild the content.
574
574
# expanding many deltas into fulltexts, as well.
575
575
# If we build a cheap enough 'strip', then we could try a strip,
576
576
# if that expands the content, we then rebuild.
577
self._rebuild_block()
577
return 'rebuild', last_byte_used
579
def _check_rebuild_block(self):
580
action, last_byte_used = self._check_rebuild_action()
584
self._trim_block(last_byte_used)
585
elif action == 'rebuild':
586
self._rebuild_block()
588
raise ValueError('unknown rebuild action: %r' % (action,))
579
590
def _wire_bytes(self):
580
591
"""Return a byte stream suitable for transmitting over the wire."""
1587
1598
if record.storage_kind == 'groupcompress-block':
1588
1599
# Check to see if we really want to re-use this block
1589
1600
insert_manager = record._manager
1601
insert_manager._check_rebuild_block()
1590
1602
if len(insert_manager._factories) == 1:
1591
1603
# This block only has a single record in it
1592
1604
# Mark this block to be rebuilt
1606
1618
'groupcompress-block-ref'):
1607
1619
if insert_manager is None:
1608
1620
raise AssertionError('No insert_manager set')
1621
if insert_manager is not record._manager:
1622
raise AssertionError('insert_manager does not match'
1623
' the current record, we cannot be positive'
1624
' that the appropriate content was inserted.'
1609
1626
value = "%d %d %d %d" % (block_start, block_length,
1610
1627
record._start, record._end)
1611
1628
nodes = [(record.key, value, (record.parents,))]