Le 21/01/2016 17:48, Jim Jagielski a écrit :
Where are we with this? Trunk uses this. Should a backport
proposal be done for 2.4??
+++1
(trying to keep trunk and 2.4.x more or less in line will be a nightmare
as long as this is not synch)
BTW, one of my reticence for such a big patch was related to the fact
that apr_table_ functions would not get the speed increase. So why
bother for just a "half patch" ?
I was wrong.
apr_table_ functions first make a quick, case insensitive, test using
the COMPUTE_KEY_CHECKSUM macro.
Here, the case-insensitive test is not made byte by byte using a lookup
table, but up to the 4 first bytes are converted to uppercase using a "&
0xdf".
The "slow" strcasecmp is only performed afterwards if these 4 bytes
don't match.
Such an implementation could be benchmarked against latest Yann's
version to see if a few test/shift/and statements perform better than
memory access in a lookup table.
This also means that APR is already a mix of "ASCII case-folding, POSIX
compliant" (i.e. takes advantage of upper = lower & 0xdf) and local
codepage aware functions (i.e. strcasecmp) when using apr_table_ functions.
CJ
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
#if APR_CHARSET_EBCDIC
#define CASE_MASK 0xbfbfbfbf
#else
#define CASE_MASK 0xdfdfdfdf
#endif
[...]
/* Compute the "checksum" for a key, consisting of the first
* 4 bytes, normalized for case-insensitivity and packed into
* an int...this checksum allows us to do a single integer
* comparison as a fast check to determine whether we can
* skip a strcasecmp
*/
#define COMPUTE_KEY_CHECKSUM(key, checksum) \
{ \
const char *k = (key); \
apr_uint32_t c = (apr_uint32_t)*k; \
(checksum) = c; \
(checksum) <<= 8; \
if (c) { \
c = (apr_uint32_t)*++k; \
checksum |= c; \
} \
(checksum) <<= 8; \
if (c) { \
c = (apr_uint32_t)*++k; \
checksum |= c; \
} \
(checksum) <<= 8; \
if (c) { \
c = (apr_uint32_t)*++k; \
checksum |= c; \
} \
checksum &= CASE_MASK; \
}