You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2015/01/25 20:21:20 UTC
svn commit: r1654690 - in /subversion/trunk/subversion/libsvn_ra_serf:
property.c ra_serf.h stat.c
Author: rhuijben
Date: Sun Jan 25 19:21:20 2015
New Revision: 1654690
URL: http://svn.apache.org/r1654690
Log:
Refactor the stat function in ra_serf to avoid more unneeded intermediate
state in hashtables. We can just process the information directly now.
* subversion/libsvn_ra_serf/property.c
(svn_ra_serf__walk_node_props): Remove function.
* subversion/libsvn_ra_serf/ra_serf.h
(svn_ra_serf__walker_visitor_t): Remove typedef.
(svn_ra_serf__walk_node_props): Remove function.
* subversion/libsvn_ra_serf/stat.c
(fetch_path_props): Remove function. Fold into callers.
(get_resource_type): Remove function. Fold into caller.
(svn_ra_serf__check_path): Integrate fetch_path_props and
get_resource_type.
(dirent_walker_baton_t): Rename to...
(fill_dirent_baton_t): ... this.
(dirent_walker): Rename to...
(fill_dirent_propfunc): ... this. Implement svn_ra_serf__prop_func_t and
re-organize if to make most likely results take less checks.
(svn_ra_serf__stat): Create a propfind handler directly, instead of
fetching a hash with data and then walking it with the same callback
that could just handle the data directly.
(get_dir_dirents_cb): Update caller.
Modified:
subversion/trunk/subversion/libsvn_ra_serf/property.c
subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
subversion/trunk/subversion/libsvn_ra_serf/stat.c
Modified: subversion/trunk/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/property.c?rev=1654690&r1=1654689&r2=1654690&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/property.c Sun Jan 25 19:21:20 2015
@@ -579,52 +579,6 @@ svn_ra_serf__fetch_node_props(apr_hash_t
return SVN_NO_ERROR;
}
-
-svn_error_t *
-svn_ra_serf__walk_node_props(apr_hash_t *props,
- svn_ra_serf__walker_visitor_t walker,
- void *baton,
- apr_pool_t *scratch_pool)
-{
- apr_pool_t *iterpool;
- apr_hash_index_t *ns_hi;
-
- iterpool = svn_pool_create(scratch_pool);
- for (ns_hi = apr_hash_first(scratch_pool, props); ns_hi;
- ns_hi = apr_hash_next(ns_hi))
- {
- void *ns_val;
- const void *ns_name;
- apr_hash_index_t *name_hi;
-
- /* NOTE: We do not clear ITERPOOL in this loop. Generally, there are
- very few namespaces, so this loop will not have many iterations.
- Instead, ITERPOOL is used for the inner loop. */
-
- apr_hash_this(ns_hi, &ns_name, NULL, &ns_val);
-
- for (name_hi = apr_hash_first(scratch_pool, ns_val); name_hi;
- name_hi = apr_hash_next(name_hi))
- {
- void *prop_val;
- const void *prop_name;
-
- /* See note above, regarding clearing of this pool. */
- svn_pool_clear(iterpool);
-
- apr_hash_this(name_hi, &prop_name, NULL, &prop_val);
-
- SVN_ERR(walker(baton, ns_name, prop_name, prop_val, iterpool));
- }
- }
- svn_pool_destroy(iterpool);
-
- return SVN_NO_ERROR;
-}
-
-
-
-
const char *
svn_ra_serf__svnname_from_wirename(const char *ns,
const char *name,
Modified: subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h?rev=1654690&r1=1654689&r2=1654690&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h Sun Jan 25 19:21:20 2015
@@ -1019,24 +1019,6 @@ svn_ra_serf__fetch_dav_prop(const char *
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-
-/** Property walker functions **/
-
-typedef svn_error_t *
-(*svn_ra_serf__walker_visitor_t)(void *baton,
- const char *ns,
- const char *name,
- const svn_string_t *val,
- apr_pool_t *pool);
-
-/* Like walk_all_props(), but a 2-level hash. */
-svn_error_t *
-svn_ra_serf__walk_node_props(apr_hash_t *props,
- svn_ra_serf__walker_visitor_t walker,
- void *baton,
- apr_pool_t *scratch_pool);
-
-
/* Map a property name, as passed over the wire, into its corresponding
Subversion-internal name. The returned name will be a static value,
or allocated within RESULT_POOL.
Modified: subversion/trunk/subversion/libsvn_ra_serf/stat.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/stat.c?rev=1654690&r1=1654689&r2=1654690&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/stat.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/stat.c Sun Jan 25 19:21:20 2015
@@ -48,22 +48,24 @@
-static svn_error_t *
-fetch_path_props(apr_hash_t **props,
- svn_ra_serf__session_t *session,
- const char *session_relpath,
- svn_revnum_t revision,
- const svn_ra_serf__dav_props_t *desired_props,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+/* Implements svn_ra__vtable_t.check_path(). */
+svn_error_t *
+svn_ra_serf__check_path(svn_ra_session_t *ra_session,
+ const char *relpath,
+ svn_revnum_t revision,
+ svn_node_kind_t *kind,
+ apr_pool_t *scratch_pool)
{
+ svn_ra_serf__session_t *session = ra_session->priv;
+ apr_hash_t *props;
+ svn_error_t *err;
const char *url;
url = session->session_url.path;
/* If we have a relative path, append it. */
- if (session_relpath)
- url = svn_path_url_add_component2(url, session_relpath, scratch_pool);
+ if (relpath)
+ url = svn_path_url_add_component2(url, relpath, scratch_pool);
/* If we were given a specific revision, get a URL that refers to that
specific revision (rather than floating with HEAD). */
@@ -77,57 +79,10 @@ fetch_path_props(apr_hash_t **props,
/* URL is stable, so we use SVN_INVALID_REVNUM since it is now irrelevant.
Or we started with SVN_INVALID_REVNUM and URL may be floating. */
- SVN_ERR(svn_ra_serf__fetch_node_props(props, session,
- url, SVN_INVALID_REVNUM,
- desired_props,
- result_pool, scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-get_resource_type(svn_node_kind_t *kind,
- apr_hash_t *props)
-{
- apr_hash_t *dav_props;
- const char *res_type;
-
- dav_props = apr_hash_get(props, "DAV:", 4);
- res_type = svn_prop_get_value(dav_props, "resourcetype");
- if (!res_type)
- {
- /* How did this happen? */
- return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
- _("The PROPFIND response did not include the "
- "requested resourcetype value"));
- }
-
- if (strcmp(res_type, "collection") == 0)
- {
- *kind = svn_node_dir;
- }
- else
- {
- *kind = svn_node_file;
- }
-
- return SVN_NO_ERROR;
-}
-
-/* Implements svn_ra__vtable_t.check_path(). */
-svn_error_t *
-svn_ra_serf__check_path(svn_ra_session_t *ra_session,
- const char *rel_path,
- svn_revnum_t revision,
- svn_node_kind_t *kind,
- apr_pool_t *pool)
-{
- svn_ra_serf__session_t *session = ra_session->priv;
- apr_hash_t *props;
-
- svn_error_t *err = fetch_path_props(&props, session, rel_path,
- revision, check_path_props,
- pool, pool);
+ err = svn_ra_serf__fetch_node_props(&props, session,
+ url, SVN_INVALID_REVNUM,
+ check_path_props,
+ scratch_pool, scratch_pool);
if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
{
@@ -136,18 +91,35 @@ svn_ra_serf__check_path(svn_ra_session_t
}
else
{
+ apr_hash_t *dav_props;
+ const char *res_type;
+
/* Any other error, raise to caller. */
- if (err)
- return svn_error_trace(err);
+ SVN_ERR(err);
+
+ dav_props = apr_hash_get(props, "DAV:", 4);
+ res_type = svn_prop_get_value(dav_props, "resourcetype");
+ if (!res_type)
+ {
+ /* How did this happen? */
+ return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
+ _("The PROPFIND response did not include the "
+ "requested resourcetype value"));
+ }
- SVN_ERR(get_resource_type(kind, props));
+ if (strcmp(res_type, "collection") == 0)
+ *kind = svn_node_dir;
+ else
+ *kind = svn_node_file;
}
return SVN_NO_ERROR;
}
-struct dirent_walker_baton_t {
+/* Baton for fill_dirent_propfunc() */
+struct fill_dirent_baton_t
+{
/* Update the fields in this entry. */
svn_dirent_t *entry;
@@ -157,76 +129,78 @@ struct dirent_walker_baton_t {
apr_pool_t *result_pool;
};
+/* Implements svn_ra_serf__prop_func_t */
static svn_error_t *
-dirent_walker(void *baton,
- const char *ns,
- const char *name,
- const svn_string_t *val,
- apr_pool_t *scratch_pool)
+fill_dirent_propfunc(void *baton,
+ const char *path,
+ const char *ns,
+ const char *name,
+ const svn_string_t *val,
+ apr_pool_t *scratch_pool)
{
- struct dirent_walker_baton_t *dwb = baton;
+ struct fill_dirent_baton_t *fdb = baton;
- if (strcmp(ns, SVN_DAV_PROP_NS_CUSTOM) == 0)
- {
- dwb->entry->has_props = TRUE;
- }
- else if (strcmp(ns, SVN_DAV_PROP_NS_SVN) == 0)
- {
- dwb->entry->has_props = TRUE;
- }
- else if (strcmp(ns, SVN_DAV_PROP_NS_DAV) == 0)
- {
- if(strcmp(name, "deadprop-count") == 0)
- {
- if (*val->data)
- {
- apr_int64_t deadprop_count;
- SVN_ERR(svn_cstring_atoi64(&deadprop_count, val->data));
- dwb->entry->has_props = deadprop_count > 0;
- if (dwb->supports_deadprop_count)
- *dwb->supports_deadprop_count = svn_tristate_true;
- }
- else if (dwb->supports_deadprop_count)
- *dwb->supports_deadprop_count = svn_tristate_false;
- }
- }
- else if (strcmp(ns, "DAV:") == 0)
+ if (strcmp(ns, "DAV:") == 0)
{
if (strcmp(name, SVN_DAV__VERSION_NAME) == 0)
{
apr_int64_t rev;
SVN_ERR(svn_cstring_atoi64(&rev, val->data));
- dwb->entry->created_rev = (svn_revnum_t)rev;
+ fdb->entry->created_rev = (svn_revnum_t)rev;
}
else if (strcmp(name, "creator-displayname") == 0)
{
- dwb->entry->last_author = apr_pstrdup(dwb->result_pool, val->data);
+ fdb->entry->last_author = apr_pstrdup(fdb->result_pool, val->data);
}
else if (strcmp(name, SVN_DAV__CREATIONDATE) == 0)
{
- SVN_ERR(svn_time_from_cstring(&dwb->entry->time,
+ SVN_ERR(svn_time_from_cstring(&fdb->entry->time,
val->data,
- dwb->result_pool));
+ fdb->result_pool));
}
else if (strcmp(name, "getcontentlength") == 0)
{
/* 'getcontentlength' property is empty for directories. */
if (val->len)
{
- SVN_ERR(svn_cstring_atoi64(&dwb->entry->size, val->data));
+ SVN_ERR(svn_cstring_atoi64(&fdb->entry->size, val->data));
}
}
else if (strcmp(name, "resourcetype") == 0)
{
if (strcmp(val->data, "collection") == 0)
{
- dwb->entry->kind = svn_node_dir;
+ fdb->entry->kind = svn_node_dir;
}
else
{
- dwb->entry->kind = svn_node_file;
+ fdb->entry->kind = svn_node_file;
+ }
+ }
+ }
+ else if (strcmp(ns, SVN_DAV_PROP_NS_CUSTOM) == 0)
+ {
+ fdb->entry->has_props = TRUE;
+ }
+ else if (strcmp(ns, SVN_DAV_PROP_NS_SVN) == 0)
+ {
+ fdb->entry->has_props = TRUE;
+ }
+ else if (strcmp(ns, SVN_DAV_PROP_NS_DAV) == 0)
+ {
+ if(strcmp(name, "deadprop-count") == 0)
+ {
+ if (*val->data)
+ {
+ apr_int64_t deadprop_count;
+ SVN_ERR(svn_cstring_atoi64(&deadprop_count, val->data));
+ fdb->entry->has_props = deadprop_count > 0;
+ if (fdb->supports_deadprop_count)
+ *fdb->supports_deadprop_count = svn_tristate_true;
}
+ else if (fdb->supports_deadprop_count)
+ *fdb->supports_deadprop_count = svn_tristate_false;
}
}
@@ -308,21 +282,49 @@ get_dirent_props(apr_uint32_t dirent_fie
/* Implements svn_ra__vtable_t.stat(). */
svn_error_t *
svn_ra_serf__stat(svn_ra_session_t *ra_session,
- const char *rel_path,
+ const char *relpath,
svn_revnum_t revision,
svn_dirent_t **dirent,
apr_pool_t *pool)
{
svn_ra_serf__session_t *session = ra_session->priv;
- apr_hash_t *props;
svn_error_t *err;
- struct dirent_walker_baton_t dwb;
+ struct fill_dirent_baton_t fdb;
svn_tristate_t deadprop_count = svn_tristate_unknown;
+ svn_ra_serf__handler_t *handler;
+ const char *url;
+
+ url = session->session_url.path;
+
+ /* If we have a relative path, append it. */
+ if (relpath)
+ url = svn_path_url_add_component2(url, relpath, pool);
+
+ /* If we were given a specific revision, get a URL that refers to that
+ specific revision (rather than floating with HEAD). */
+ if (SVN_IS_VALID_REVNUM(revision))
+ {
+ SVN_ERR(svn_ra_serf__get_stable_url(&url, NULL /* latest_revnum */,
+ session,
+ url, revision,
+ pool, pool));
+ }
+
+ fdb.entry = svn_dirent_create(pool);
+ fdb.supports_deadprop_count = &deadprop_count;
+ fdb.result_pool = pool;
- err = fetch_path_props(&props,
- session, rel_path, revision,
- get_dirent_props(SVN_DIRENT_ALL, session, pool),
- pool, pool);
+ SVN_ERR(svn_ra_serf__create_propfind_handler(&handler, session, url,
+ SVN_INVALID_REVNUM, "0",
+ get_dirent_props(SVN_DIRENT_ALL,
+ session,
+ pool),
+ fill_dirent_propfunc, &fdb, pool));
+
+ err = svn_ra_serf__context_run_one(handler, pool);
+
+ if (!err && handler->sline.code != 207)
+ err = svn_ra_serf__unexpected_status(handler);
if (err)
{
if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
@@ -335,31 +337,25 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
return svn_error_trace(err);
}
- dwb.entry = svn_dirent_create(pool);
- dwb.supports_deadprop_count = &deadprop_count;
- dwb.result_pool = pool;
- SVN_ERR(svn_ra_serf__walk_node_props(props, dirent_walker, &dwb, pool));
-
if (deadprop_count == svn_tristate_false
&& session->supports_deadprop_count == svn_tristate_unknown
- && !dwb.entry->has_props)
+ && !fdb.entry->has_props)
{
/* We have to requery as the server didn't give us the right
information */
session->supports_deadprop_count = svn_tristate_false;
- SVN_ERR(fetch_path_props(&props,
- session, rel_path, SVN_INVALID_REVNUM,
- get_dirent_props(SVN_DIRENT_ALL, session, pool),
- pool, pool));
+ /* Run the same handler again */
+ SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
- SVN_ERR(svn_ra_serf__walk_node_props(props, dirent_walker, &dwb, pool));
+ if (handler->sline.code != 207)
+ return svn_error_trace(svn_ra_serf__unexpected_status(handler));
}
if (deadprop_count != svn_tristate_unknown)
session->supports_deadprop_count = deadprop_count;
- *dirent = dwb.entry;
+ *dirent = fdb.entry;
return SVN_NO_ERROR;
}
@@ -375,7 +371,7 @@ struct get_dir_baton_t
const char *path;
};
-/* Implements svn_ra_serf__prop_func */
+/* Implements svn_ra_serf__prop_func_t */
static svn_error_t *
get_dir_dirents_cb(void *baton,
const char *path,
@@ -391,22 +387,22 @@ get_dir_dirents_cb(void *baton,
if (relpath && relpath[0] != '\0')
{
- struct dirent_walker_baton_t dwb;
+ struct fill_dirent_baton_t fdb;
relpath = svn_path_uri_decode(relpath, scratch_pool);
- dwb.entry = svn_hash_gets(db->dirents, relpath);
+ fdb.entry = svn_hash_gets(db->dirents, relpath);
- if (!dwb.entry)
+ if (!fdb.entry)
{
- dwb.entry = svn_dirent_create(db->result_pool);
+ fdb.entry = svn_dirent_create(db->result_pool);
svn_hash_sets(db->dirents,
apr_pstrdup(db->result_pool, relpath),
- dwb.entry);
+ fdb.entry);
}
- dwb.result_pool = db->result_pool;
- dwb.supports_deadprop_count = &db->supports_deadprop_count;
- SVN_ERR(dirent_walker(&dwb, ns, name, value, scratch_pool));
+ fdb.result_pool = db->result_pool;
+ fdb.supports_deadprop_count = &db->supports_deadprop_count;
+ SVN_ERR(fill_dirent_propfunc(&fdb, path, ns, name, value, scratch_pool));
}
else if (relpath && !db->is_directory)
{