Alien-SVN
view release on metacpan or search on metacpan
src/subversion/tools/dev/fsfs-reorg.c view on Meta::CPAN
switch (fragment->kind)
{
case dir_fragment:
*length = content->len + 16;
break;
case noderev_fragment:
*length = content->len + 3;
break;
default:
*length = content->len;
break;
}
else
*length = content->len;
return SVN_NO_ERROR;
}
/* Move the FRAGMENT to global file offset NEW_POSITION. Update the target
* location info of the underlying object as well.
*/
static void
move_fragment(fragment_t *fragment,
apr_size_t new_position)
{
revision_info_t *info;
representation_t *representation;
noderev_t *node;
/* move the fragment */
fragment->position = new_position;
/* move the underlying object */
switch (fragment->kind)
{
case header_fragment:
info = fragment->data;
info->target.offset = new_position;
break;
case changes_fragment:
info = fragment->data;
info->target.changes = new_position - info->target.offset;
break;
case property_fragment:
case file_fragment:
case dir_fragment:
representation = fragment->data;
representation->target.offset = new_position;
break;
case noderev_fragment:
node = fragment->data;
node->target.offset = new_position;
break;
}
}
/* Move the fragments in PACK's target fragment list to their final offsets.
* This may require several iterations if the fudge factors turned out to
* be insufficient. Use POOL for allocations.
*/
static svn_error_t *
pack_revisions(fs_fs_t *fs,
revision_pack_t *pack,
apr_pool_t *pool)
{
int i;
fragment_t *fragment, *next;
svn_boolean_t needed_to_expand;
revision_info_t *info;
apr_size_t current_pos, len, old_len;
apr_pool_t *itempool = svn_pool_create(pool);
/* update all directory reps. Chances are that most of the target rep
* sizes are now close to accurate. */
SVN_ERR(update_noderevs(fs, pack, pool));
/* compression phase: pack all fragments tightly with only a very small
* fudge factor. This should cause offsets to shrink, thus all the
* actual fragment rate should tend to be even smaller afterwards. */
current_pos = pack->info->nelts > 1 ? 64 : 0;
for (i = 0; i + 1 < pack->fragments->nelts; ++i)
{
fragment = &APR_ARRAY_IDX(pack->fragments, i, fragment_t);
SVN_ERR(get_content_length(&len, fs, fragment, TRUE, itempool));
move_fragment(fragment, current_pos);
current_pos += len;
svn_pool_clear(itempool);
}
/* don't forget the final fragment (last revision's revision header) */
fragment = &APR_ARRAY_IDX(pack->fragments, pack->fragments->nelts-1, fragment_t);
fragment->position = current_pos;
/* expansion phase: check whether all fragments fit into their allotted
* slots. Grow them geometrically if they don't fit. Retry until they
* all do fit.
* Note: there is an upper limit to which fragments can grow. So, this
* loop will terminate. Often, no expansion will be necessary at all. */
do
{
needed_to_expand = FALSE;
current_pos = pack->info->nelts > 1 ? 64 : 0;
for (i = 0; i + 1 < pack->fragments->nelts; ++i)
{
fragment = &APR_ARRAY_IDX(pack->fragments, i, fragment_t);
next = &APR_ARRAY_IDX(pack->fragments, i + 1, fragment_t);
old_len = next->position - fragment->position;
SVN_ERR(get_content_length(&len, fs, fragment, FALSE, itempool));
if (len > old_len)
{
len = (apr_size_t)(len * 1.1) + 10;
needed_to_expand = TRUE;
}
( run in 0.797 second using v1.01-cache-2.11-cpan-71847e10f99 )