Greg Hudson wrote:
>If there's no measurable benefit from using fast_strtoul10, I'd prefer
>using the real strtoul() for conciseness. (And there definitely doesn't
>need to be a commented-out strtoui10 there.) As has been pointed out
>beofre, there's no real portability issue here.
>
>And you need a log message, as documented in HACKING.
>
>
* subversion/libsvn_subr/time.c (svn_time_from_cstring): Replace sscanf
with strtoul for better performance.
Index: subversion/libsvn_subr/time.c
===================================================================
--- subversion/libsvn_subr/time.c (revision 3971)
+++ subversion/libsvn_subr/time.c (working copy)
@@ -142,44 +142,53 @@
return -1;
}
-
svn_error_t *
svn_time_from_cstring(apr_time_t *when, const char *data, apr_pool_t *pool)
{
apr_time_exp_t exploded_time;
apr_status_t apr_err;
char wday[4], month[4];
+ const char *c = data;
- /* First try the new timestamp format. */
- if (sscanf (data,
- timestamp_format,
- &exploded_time.tm_year,
- &exploded_time.tm_mon,
- &exploded_time.tm_mday,
- &exploded_time.tm_hour,
- &exploded_time.tm_min,
- &exploded_time.tm_sec,
- &exploded_time.tm_usec) == 7)
- {
- exploded_time.tm_year -= 1900;
- exploded_time.tm_mon -= 1;
- exploded_time.tm_wday = 0;
- exploded_time.tm_yday = 0;
- exploded_time.tm_isdst = 0;
- exploded_time.tm_gmtoff = 0;
-
- apr_err = apr_implode_gmt (when, &exploded_time);
- if(apr_err != APR_SUCCESS)
- {
- return svn_error_createf (SVN_ERR_BAD_DATE, apr_err, NULL,
- "Date conversion failed.");
- }
-
- return SVN_NO_ERROR;
- }
- /* Then try the compatibility option. */
- else if (sscanf (data,
- old_timestamp_format,
+ /* Open-code parsing of the new timestamp format, as this
+ is a hot path for reading the entries file.
+
+ This format looks like:
+ "2001-08-31T04:24:14.966996Z" */
+ exploded_time.tm_year = strtoul(c, (char**)&c, 10);
+ if (*c++ != '-') goto fail;
+ exploded_time.tm_mon = strtoul(c, (char**)&c, 10);
+ if (*c++ != '-') goto fail;
+ exploded_time.tm_mday = strtoul(c, (char**)&c, 10);
+ if (*c++ != 'T') goto fail;
+ exploded_time.tm_hour = strtoul(c, (char**)&c, 10);
+ if (*c++ != ':') goto fail;
+ exploded_time.tm_min = strtoul(c, (char**)&c, 10);
+ if (*c++ != ':') goto fail;
+ exploded_time.tm_sec = strtoul(c, (char**)&c, 10);
+ if (*c++ != '.') goto fail;
+ exploded_time.tm_usec = strtoul(c, (char**)&c, 10);
+ if (*c++ != 'Z') goto fail;
+
+ exploded_time.tm_year -= 1900;
+ exploded_time.tm_mon -= 1;
+ exploded_time.tm_wday = 0;
+ exploded_time.tm_yday = 0;
+ exploded_time.tm_isdst = 0;
+ exploded_time.tm_gmtoff = 0;
+
+ apr_err = apr_implode_gmt(when, &exploded_time);
+ if (apr_err == APR_SUCCESS)
+ return SVN_NO_ERROR;
+
+ return svn_error_createf(SVN_ERR_BAD_DATE, apr_err, NULL,
+ "Date conversion failed.");
+
+fail:
+ /* Try the compatibility option. This does not need to be fast,
+ as this format is no longer generated and the client will convert
+ an old-format entries file the first time it reads it. */
+ if (sscanf(data, old_timestamp_format,
wday,
&exploded_time.tm_mday,
month,
@@ -196,27 +205,22 @@
exploded_time.tm_yday -= 1;
/* Using hard coded limits for the arrays - they are going away
soon in any case. */
- exploded_time.tm_wday = find_matching_string (wday, 7, apr_day_snames);
- exploded_time.tm_mon = find_matching_string (month, 12, apr_month_snames);
+ exploded_time.tm_wday = find_matching_string(wday, 7, apr_day_snames);
+ exploded_time.tm_mon = find_matching_string(month, 12, apr_month_snames);
- apr_err = apr_implode_gmt (when, &exploded_time);
- if(apr_err != APR_SUCCESS)
- {
- return svn_error_createf (SVN_ERR_BAD_DATE, apr_err, NULL,
- "Date conversion failed.");
- }
+ apr_err = apr_implode_gmt(when, &exploded_time);
+ if (apr_err == APR_SUCCESS)
+ return SVN_NO_ERROR;
- return SVN_NO_ERROR;
+ return svn_error_createf(SVN_ERR_BAD_DATE, apr_err, NULL,
+ "Date conversion failed.");
}
+
/* Timestamp is something we do not recognize. */
- else
- {
- return svn_error_createf(SVN_ERR_BAD_DATE, 0, NULL,
- "Date parsing failed.");
- }
+ return svn_error_createf(SVN_ERR_BAD_DATE, 0, NULL,
+ "Date parsing failed.");
}
-
const char *
svn_time_to_human_cstring (apr_time_t t, apr_pool_t *pool)
{
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue Dec 3 20:14:55 2002