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 )