You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by David Glasser <gl...@davidglasser.net> on 2008/01/25 18:46:38 UTC

Re: svn commit: r29023 - trunk/subversion/libsvn_fs_base

On Jan 24, 2008 9:36 PM,  <cm...@tigris.org> wrote:
> Author: cmpilato
> Date: Thu Jan 24 21:36:50 2008
> New Revision: 29023
>
> Log:
> Replace the SQLite-based implementation of mergeinfo indexing in
> libsvn_fs_base with a native Berkeley DB implementation.  (Much of
> this was inspired by -- if not copied almost wholesale from -- the
> FSFS implementation of the same.)


>
> Modified: trunk/subversion/libsvn_fs_base/tree.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_fs_base/tree.c?pathrev=29023&r1=29022&r2=29023
> ==============================================================================
> --- trunk/subversion/libsvn_fs_base/tree.c      (original)
> +++ trunk/subversion/libsvn_fs_base/tree.c      Thu Jan 24 21:36:50 2008
> @@ -469,6 +469,8 @@
>  } parent_path_t;
>
>
> +/* Return the FS path for the parent path chain object PARENT_PATH,
> +   allocated in POOL. */
>  static const char *
>  parent_path_path(parent_path_t *parent_path,
>                   apr_pool_t *pool)
> @@ -482,6 +484,25 @@
>  }
>
>
> +/* Return the FS path for the parent path chain object CHILD relative
> +   to its ANCESTOR in the same chain, allocated in POOL.  */
> +static const char *
> +parent_path_relpath(parent_path_t *child,
> +                    parent_path_t *ancestor,
> +                    apr_pool_t *pool)
> +{
> +  const char *path_so_far = "";
> +  parent_path_t *this_node = child;
> +  while (this_node != ancestor)
> +    {
> +      assert(this_node != NULL);
> +      path_so_far = svn_path_join(this_node->entry, path_so_far, pool);
> +      this_node = this_node->parent;
> +    }
> +  return path_so_far;
> +}
> +
> +
>  /* Choose a copy ID inheritance method *INHERIT_P to be used in the
>     event that immutable node CHILD in FS needs to be made mutable.  If
>     the inheritance method is copy_id_inherit_new, also return a
> @@ -1231,6 +1252,7 @@
>    return SVN_NO_ERROR;
>  }
>
> +
>  struct change_node_prop_args {
>    svn_fs_root_t *root;
>    const char *path;
> @@ -1240,24 +1262,6 @@
>
>
>  static svn_error_t *
> -change_txn_mergeinfo(struct change_node_prop_args *args, trail_t *trail)
> -{
> -  const char *txn_id = args->root->txn;
> -
> -  /* At least for single file merges, nodes which are direct
> -     children of the root are received without a leading slash
> -     (e.g. "/file.txt" is received as "file.txt"), so must be made
> -     absolute. */
> -  const char *canon_path = svn_fs__canonicalize_abspath(args->path,
> -                                                             trail->pool);
> -  SVN_ERR(svn_fs_base__set_txn_mergeinfo(args->root->fs, txn_id, canon_path,
> -                                         args->value, trail, trail->pool));
> -
> -  return SVN_NO_ERROR;
> -}
> -
> -
> -static svn_error_t *
>  txn_body_change_node_prop(void *baton,
>                            trail_t *trail)
>  {
> @@ -1288,9 +1292,6 @@
>    if (! proplist)
>      proplist = apr_hash_make(trail->pool);
>
> -  if (strcmp(args->name, SVN_PROP_MERGEINFO) == 0)
> -    SVN_ERR(change_txn_mergeinfo(args, trail));
> -
>    /* Set the property. */
>    apr_hash_set(proplist, args->name, APR_HASH_KEY_STRING, args->value);
>
> @@ -4685,6 +4686,458 @@
>    return SVN_NO_ERROR;
>  }
>
> +
> +
> +/* Mergeinfo Queries */
> +
> +/* Examine directory NODE's immediately children for mergeinfo.
> +
> +   For those which have explicit mergeinfo, add their mergeinfo to
> +   RESULT_CATALOG (allocated in RESULT_CATALOG's pool).
> +
> +   For those which don't, but sit atop trees which contain mergeinfo
> +   somewhere deeper, add them to *CHILDREN_ATOP_MERGEINFO_TREES, a
> +   hash mapping dirent names to dag_node_t * objects, allocated
> +   from that hash's pool.
> +
> +   For those which neither have explicit mergeinfo nor sit atop trees
> +   which contain mergeinfo, ignore them.
> +
> +   Use TRAIL->pool for temporary allocations. */
> +
> +struct get_mergeinfo_data_and_entries_baton
> +{
> +  apr_hash_t *result_catalog;
> +  apr_hash_t *children_atop_mergeinfo_trees;
> +  dag_node_t *node;
> +  const char *node_path;
> +};
> +
> +static svn_error_t *
> +txn_body_get_mergeinfo_data_and_entries(void *baton, trail_t *trail)
> +{
> +  struct get_mergeinfo_data_and_entries_baton *args = baton;
> +  dag_node_t *node = args->node;
> +  apr_hash_t *entries;
> +  apr_hash_index_t *hi;
> +  apr_pool_t *iterpool = svn_pool_create(trail->pool);
> +  apr_pool_t *result_pool = apr_hash_pool_get(args->result_catalog);
> +  apr_pool_t *children_pool =
> +    apr_hash_pool_get(args->children_atop_mergeinfo_trees);
> +
> +  assert(svn_fs_base__dag_node_kind(node) == svn_node_dir);
> +
> +  SVN_ERR(svn_fs_base__dag_dir_entries(&entries, node, trail, trail->pool));
> +  for (hi = apr_hash_first(NULL, entries); hi; hi = apr_hash_next(hi))
> +    {
> +      void *val;
> +      svn_fs_dirent_t *dirent;
> +      const svn_fs_id_t *child_id;
> +      dag_node_t *child_node;
> +      svn_boolean_t has_mergeinfo;
> +      apr_int64_t kid_count;
> +
> +      svn_pool_clear(iterpool);
> +      apr_hash_this(hi, NULL, NULL, &val);
> +      dirent = val;
> +      child_id = dirent->id;
> +
> +      /* Get the node for this child. */
> +      SVN_ERR(svn_fs_base__dag_get_node(&child_node, trail->fs, child_id,
> +                                        trail, iterpool));
> +
> +      /* Query the child node's mergeinfo stats. */
> +      SVN_ERR(svn_fs_base__dag_get_mergeinfo_stats(&has_mergeinfo, &kid_count,
> +                                                   child_node, trail,
> +                                                   iterpool));
> +
> +      /* If the child has mergeinfo, add it to the result catalog. */
> +      if (has_mergeinfo)
> +        {
> +          apr_hash_t *plist, *child_mergeinfo_hash;
> +          svn_string_t *pval;
> +
> +          SVN_ERR(svn_fs_base__dag_get_proplist(&plist, child_node,
> +                                                trail, iterpool));
> +          pval = apr_hash_get(plist, SVN_PROP_MERGEINFO, APR_HASH_KEY_STRING);
> +          if (! pval)
> +            {
> +              svn_string_t *id_str = svn_fs_base__id_unparse(child_id,
> +                                                             iterpool);
> +              return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
> +                                       _("Node-revision '%s' claims to have "
> +                                         "mergeinfo but doesn't"),
> +                                       id_str->data);
> +            }
> +          SVN_ERR(svn_mergeinfo_parse(&child_mergeinfo_hash, pval->data,
> +                                      result_pool));
> +          apr_hash_set(args->result_catalog,
> +                       svn_path_join(args->node_path, dirent->name,
> +                                     result_pool),
> +                       APR_HASH_KEY_STRING,
> +                       child_mergeinfo_hash);
> +        }
> +
> +      /* Otherwise, if the child has descendants with mergeinfo, add
> +         it to the children_atop_mergeinfo_trees hash. */
> +      else if (kid_count > 0)

I don't think this "else" here is correct.

> +        {
> +          if (svn_fs_base__dag_node_kind(child_node) != svn_node_dir)
> +            {
> +              svn_string_t *id_str = svn_fs_base__id_unparse(child_id,
> +                                                             iterpool);
> +              return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
> +                                       _("Node-revision '%s' claims to sit "
> +                                         "atop a tree containing mergeinfo "
> +                                         "but is not a directory"),
> +                                       id_str->data);
> +            }
> +          apr_hash_set(args->children_atop_mergeinfo_trees,
> +                       apr_pstrdup(children_pool, dirent->name),
> +                       APR_HASH_KEY_STRING,
> +                       svn_fs_base__dag_dup(child_node, children_pool));
> +        }
> +    }
> +
> +  svn_pool_destroy(iterpool);
> +  return SVN_NO_ERROR;
> +}

--dave



-- 
David Glasser | glasser@davidglasser.net | http://www.davidglasser.net/

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: svn commit: r29023 - trunk/subversion/libsvn_fs_base

Posted by David Glasser <gl...@davidglasser.net>.
On Jan 25, 2008 10:52 AM, C. Michael Pilato <cm...@collab.net> wrote:
>
> David Glasser wrote:
>
> >> +      /* If the child has mergeinfo, add it to the result catalog. */
> >> +      if (has_mergeinfo)
> >> +        {
> >> +          apr_hash_t *plist, *child_mergeinfo_hash;
> >> +          svn_string_t *pval;
> >> +
> >> +          SVN_ERR(svn_fs_base__dag_get_proplist(&plist, child_node,
> >> +                                                trail, iterpool));
> >> +          pval = apr_hash_get(plist, SVN_PROP_MERGEINFO, APR_HASH_KEY_STRING);
> >> +          if (! pval)
> >> +            {
> >> +              svn_string_t *id_str = svn_fs_base__id_unparse(child_id,
> >> +                                                             iterpool);
> >> +              return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
> >> +                                       _("Node-revision '%s' claims to have "
> >> +                                         "mergeinfo but doesn't"),
> >> +                                       id_str->data);
> >> +            }
> >> +          SVN_ERR(svn_mergeinfo_parse(&child_mergeinfo_hash, pval->data,
> >> +                                      result_pool));
> >> +          apr_hash_set(args->result_catalog,
> >> +                       svn_path_join(args->node_path, dirent->name,
> >> +                                     result_pool),
> >> +                       APR_HASH_KEY_STRING,
> >> +                       child_mergeinfo_hash);
> >> +        }
> >> +
> >> +      /* Otherwise, if the child has descendants with mergeinfo, add
> >> +         it to the children_atop_mergeinfo_trees hash. */
> >> +      else if (kid_count > 0)
> >
> > I don't think this "else" here is correct.
>
> Hrm.  Oh!  Does the code not cover the case where the item itself has
> mergeinfo *and* sits atop a tree of more mergeinfo?

Right.

--dave


-- 
David Glasser | glasser@davidglasser.net | http://www.davidglasser.net/

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: svn commit: r29023 - trunk/subversion/libsvn_fs_base

Posted by "C. Michael Pilato" <cm...@collab.net>.
David Glasser wrote:

>> +      /* If the child has mergeinfo, add it to the result catalog. */
>> +      if (has_mergeinfo)
>> +        {
>> +          apr_hash_t *plist, *child_mergeinfo_hash;
>> +          svn_string_t *pval;
>> +
>> +          SVN_ERR(svn_fs_base__dag_get_proplist(&plist, child_node,
>> +                                                trail, iterpool));
>> +          pval = apr_hash_get(plist, SVN_PROP_MERGEINFO, APR_HASH_KEY_STRING);
>> +          if (! pval)
>> +            {
>> +              svn_string_t *id_str = svn_fs_base__id_unparse(child_id,
>> +                                                             iterpool);
>> +              return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
>> +                                       _("Node-revision '%s' claims to have "
>> +                                         "mergeinfo but doesn't"),
>> +                                       id_str->data);
>> +            }
>> +          SVN_ERR(svn_mergeinfo_parse(&child_mergeinfo_hash, pval->data,
>> +                                      result_pool));
>> +          apr_hash_set(args->result_catalog,
>> +                       svn_path_join(args->node_path, dirent->name,
>> +                                     result_pool),
>> +                       APR_HASH_KEY_STRING,
>> +                       child_mergeinfo_hash);
>> +        }
>> +
>> +      /* Otherwise, if the child has descendants with mergeinfo, add
>> +         it to the children_atop_mergeinfo_trees hash. */
>> +      else if (kid_count > 0)
> 
> I don't think this "else" here is correct.

Hrm.  Oh!  Does the code not cover the case where the item itself has 
mergeinfo *and* sits atop a tree of more mergeinfo?

-- 
C. Michael Pilato <cm...@collab.net>
CollabNet   <>   www.collab.net   <>   Distributed Development On Demand