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;                     \
}

Reply via email to