From: Francesco Chemolli Date: Wed, 14 Sep 2011 18:21:46 +0000 (+0200) Subject: Introduced experimental strblob class to more efficiently handle Cache-Control header... X-Git-Tag: BumpSslServerFirst.take01~126^2~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7ebe76de5fe1eaa10026ad34ab6e5f6437775552;p=thirdparty%2Fsquid.git Introduced experimental strblob class to more efficiently handle Cache-Control header lookups Various performance improvements. Renamed HttpHdrCc::parseInit() to parse() Reverted some changes in HTtpHdrCc::parse() to facilitate review. Removed useless HttpHdrCc::setSMaxAge Removed Author attribution - too many authors to single any one out Removed parametric HttpHdrCc constructor, made parametric. Removed duplicate mempool definition --- diff --git a/src/HttpHdrCc.cc b/src/HttpHdrCc.cc index c48612666b..be62067e3b 100644 --- a/src/HttpHdrCc.cc +++ b/src/HttpHdrCc.cc @@ -2,7 +2,6 @@ /* * * DEBUG: section 65 HTTP Cache Control Header - * AUTHOR: Alex Rousskov, Francesco Chemolli * * SQUID Web Proxy Cache http://www.squid-cache.org/ * ---------------------------------------------------------- @@ -41,6 +40,22 @@ #include #endif +/** dumb char* /length combo for quick lookups. + * + * Data is not copied. + * Validity of the pointed-to storage is responsibility of the caller. + * */ +class strblob { + public: + strblob(const char * ptr, size_t len): thePtr(ptr), theLen(len) {} + bool operator==(strblob &s) const { return theLen==s.theLen && 0==strncmp(thePtr,s.thePtr,theLen); } + bool operator< ( const strblob &s2) const { return strncmp(thePtr,s2.thePtr,theLen) < 0; } + + private: + const char *thePtr; + size_t theLen; +}; + /* this table is used for parsing cache control header and statistics */ typedef struct { const char *name; @@ -67,8 +82,8 @@ static HttpHeaderCcFields CcAttrs[CC_ENUM_END] = { }; /// Map an header name to its type, to expedite parsing -typedef std::map HdrCcNameToIdMap_t; -static HdrCcNameToIdMap_t HdrCcNameToIdMap; +typedef std::map CcNameToIdMap_t; +static CcNameToIdMap_t CcNameToIdMap; /// iterate over a table of http_header_cc_type structs http_hdr_cc_type &operator++ (http_hdr_cc_type &aHeader) @@ -83,11 +98,12 @@ http_hdr_cc_type &operator++ (http_hdr_cc_type &aHeader) void httpHdrCcInitModule(void) { - int32_t i; /* build lookup and accounting structures */ - for (i=0;iid); /* verify assumption: the id is the key into the array */ + const strblob k(f->name,strlen(f->name)); + CcNameToIdMap[k]=f->id; } } @@ -101,19 +117,11 @@ httpHdrCcCleanModule(void) void HttpHdrCc::clear() { - mask=0; - max_age=-1; - mask=0; - max_age=-1; - s_maxage=-1; - max_stale=-1; - stale_if_error=0; - min_fresh=-1; - other.clean(); + *this=HttpHdrCc(); } bool -HttpHdrCc::parseInit(const String & str) +HttpHdrCc::parse(const String & str) { const char *item; const char *p; /* '=' parameter */ @@ -121,11 +129,11 @@ HttpHdrCc::parseInit(const String & str) http_hdr_cc_type type; int ilen; int nlen; + HttpHdrCc *cc=this; //TODO: remove after review /* iterate through comma separated list */ while (strListGetItem(&str, ',', &item, &ilen, &pos)) { - String tmpstr; /* isolate directive name */ if ((p = (const char *)memchr(item, '=', ilen)) && (p - item < ilen)) @@ -134,23 +142,22 @@ HttpHdrCc::parseInit(const String & str) nlen = ilen; /* find type */ - tmpstr.limitInit(item,nlen); - HdrCcNameToIdMap_t::iterator i; - i=HdrCcNameToIdMap.find(tmpstr); - if (i==HdrCcNameToIdMap.end()) + const strblob tmpstr(item,nlen); + const CcNameToIdMap_t::iterator i=CcNameToIdMap.find(tmpstr); + if (i==CcNameToIdMap.end()) type=CC_OTHER; else type=i->second; // ignore known duplicate directives - if (EBIT_TEST(mask, type)) { + if (EBIT_TEST(cc->mask, type)) { if (type != CC_OTHER) { debugs(65, 2, "hdr cc: ignoring duplicate cache-directive: near '" << item << "' in '" << str << "'"); - CcAttrs[type].stat.repCount++; + ++CcAttrs[type].stat.repCount; continue; } } else { - EBIT_SET(mask, type); + EBIT_SET(cc->mask, type); } /* post-processing special cases */ @@ -158,48 +165,48 @@ HttpHdrCc::parseInit(const String & str) case CC_MAX_AGE: - if (!p || !httpHeaderParseInt(p, &max_age)) { + if (!p || !httpHeaderParseInt(p, &cc->max_age)) { debugs(65, 2, "cc: invalid max-age specs near '" << item << "'"); - max_age = -1; - EBIT_CLR(mask, type); + cc->max_age = -1; + EBIT_CLR(cc->mask, type); } break; case CC_S_MAXAGE: - if (!p || !httpHeaderParseInt(p, &s_maxage)) { + if (!p || !httpHeaderParseInt(p, &cc->s_maxage)) { debugs(65, 2, "cc: invalid s-maxage specs near '" << item << "'"); - s_maxage = -1; - EBIT_CLR(mask, type); + cc->s_maxage = -1; + EBIT_CLR(cc->mask, type); } break; case CC_MAX_STALE: - if (!p || !httpHeaderParseInt(p, &max_stale)) { + if (!p || !httpHeaderParseInt(p, &cc->max_stale)) { debugs(65, 2, "cc: max-stale directive is valid without value"); - max_stale = -1; + cc->max_stale = -1; } break; case CC_MIN_FRESH: - if (!p || !httpHeaderParseInt(p, &min_fresh)) { + if (!p || !httpHeaderParseInt(p, &cc->min_fresh)) { debugs(65, 2, "cc: invalid min-fresh specs near '" << item << "'"); - min_fresh = -1; - EBIT_CLR(mask, type); + cc->min_fresh = -1; + EBIT_CLR(cc->mask, type); } break; case CC_STALE_IF_ERROR: - if (!p || !httpHeaderParseInt(p, &stale_if_error)) { + if (!p || !httpHeaderParseInt(p, &cc->stale_if_error)) { debugs(65, 2, "cc: invalid stale-if-error specs near '" << item << "'"); - stale_if_error = -1; - EBIT_CLR(mask, type); + cc->stale_if_error = -1; + EBIT_CLR(cc->mask, type); } break; @@ -218,7 +225,7 @@ HttpHdrCc::parseInit(const String & str) } } - return (mask != 0); + return (cc->mask != 0); } void @@ -248,7 +255,7 @@ httpHdrCcPackInto(const HttpHdrCc * cc, Packer * p) if (flag == CC_MIN_FRESH) packerPrintf(p, "=%d", (int) cc->min_fresh); - pcount++; + ++pcount; } } @@ -268,17 +275,6 @@ HttpHdrCc::setMaxAge(int max_age_) EBIT_CLR(mask, CC_MAX_AGE); } -void -HttpHdrCc::setSMaxAge(int s_maxage_) -{ - s_maxage = s_maxage_; - - if (s_maxage_ >= 0) - EBIT_SET(mask, CC_S_MAXAGE); - else - EBIT_CLR(mask, CC_S_MAXAGE); -} - void httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist) { diff --git a/src/HttpHdrCc.h b/src/HttpHdrCc.h index d3adcb58c6..81ee399bf6 100644 --- a/src/HttpHdrCc.h +++ b/src/HttpHdrCc.h @@ -1,8 +1,6 @@ /* * HttpHdrCc.h * - * Created on: Sep 2, 2011 - * Author: Francesco Chemolli * * SQUID Web Proxy Cache http://www.squid-cache.org/ * ---------------------------------------------------------- @@ -38,52 +36,46 @@ #include "MemPool.h" #include "SquidString.h" -/** Http Cache-control header representation +/** Http Cache-Control header representation * - * Store, parse and output the Cache-control HTTP header. + * Store and parse the Cache-Control HTTP header. */ class HttpHdrCc { public: - int32_t mask; - int32_t max_age; - int32_t s_maxage; - int32_t max_stale; - int32_t stale_if_error; - int32_t min_fresh; - String other; - - HttpHdrCc(int32_t max_age_=-1, int32_t s_maxage_=-1, - int32_t max_stale_=-1, int32_t min_fresh_=-1) : - mask(0), max_age(max_age_), s_maxage(s_maxage_), - max_stale(max_stale_), stale_if_error(0), - min_fresh(min_fresh_) {} + explicit HttpHdrCc() : + mask(0), max_age(-1), s_maxage(-1), + max_stale(-1), stale_if_error(0), + min_fresh(-1) {} - /** reset the structure to a clear state. - * - */ + /// reset to the after-default-construction state. void clear(); - /**parses the supplied string filling in HttpHdrCc's fields. + + /**parse the supplied string filling in HttpHdrCc's fields. * * \note: internal structures are not cleaned-up beforehand. * caller must explicitly clear() beforehand if he wants that */ - bool parseInit(const String &s); + bool parse(const String &s); + /** set the max_age value * * \param max_age the new max age. Values <0 clear it. */ void setMaxAge(int32_t max_age); - /** set the s-maxage - * - * \param s_maxage the new max age. Values <0 clear it. - */ - void setSMaxAge(int32_t s_maxage); - MEMPROXY_CLASS(HttpHdrCc); + /// bit-mask for the various Cc directives, keyed on http_hdr_cc_type + int32_t mask; + int32_t max_age; + int32_t s_maxage; + int32_t max_stale; + int32_t stale_if_error; + int32_t min_fresh; + /// comma-separated string accumulating unknown Cache-control directives. + String other; }; MEMPROXY_CLASS_INLINE(HttpHdrCc); diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc index 43158c1dd5..e3fc42f80c 100644 --- a/src/HttpHeader.cc +++ b/src/HttpHeader.cc @@ -36,6 +36,7 @@ #include "squid.h" #include "base64.h" #include "HttpHdrContRange.h" +#include "HttpHdrCc.h" #include "HttpHdrSc.h" #include "HttpHeader.h" #include "MemBuf.h" @@ -1312,15 +1313,19 @@ HttpHeader::getCc() const { HttpHdrCc *cc; String s; + bool gotList; if (!CBIT_TEST(mask, HDR_CACHE_CONTROL)) return NULL; PROF_start(HttpHeader_getCc); - getList(HDR_CACHE_CONTROL, &s); + gotList=getList(HDR_CACHE_CONTROL, &s); cc=new HttpHdrCc(); - if (!cc->parseInit(s)) { + if (!gotList) + return cc; + + if (!cc->parse(s)) { delete cc; cc = NULL; } diff --git a/src/HttpHeader.h b/src/HttpHeader.h index 4cf560d8fd..778b76fc1c 100644 --- a/src/HttpHeader.h +++ b/src/HttpHeader.h @@ -37,7 +37,6 @@ #include "HttpHeaderRange.h" /* HttpHeader holds a HttpHeaderMask */ #include "HttpHeaderMask.h" -#include "HttpHdrCc.h" /* class forward declarations */ diff --git a/src/HttpReply.cc b/src/HttpReply.cc index 75bd684999..57d0449733 100644 --- a/src/HttpReply.cc +++ b/src/HttpReply.cc @@ -38,6 +38,7 @@ #include "Store.h" #include "HttpReply.h" #include "HttpHdrContRange.h" +#include "HttpHdrCc.h" #include "HttpHdrSc.h" #include "acl/FilledChecklist.h" #include "HttpRequest.h" diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 258acdc4e6..91a0e3c43b 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -37,6 +37,7 @@ #include "squid.h" #include "DnsLookupDetails.h" #include "HttpRequest.h" +#include "HttpHdrCc.h" #if USE_AUTH #include "auth/UserRequest.h" #endif diff --git a/src/enums.h b/src/enums.h index f5e2e0dbfd..a49f357857 100644 --- a/src/enums.h +++ b/src/enums.h @@ -218,7 +218,6 @@ typedef enum { MEM_DLINK_NODE, MEM_DREAD_CTRL, MEM_DWRITE_Q, - MEM_HTTP_HDR_CC, MEM_HTTP_HDR_CONTENT_RANGE, MEM_MD5_DIGEST, MEM_NETDBENTRY, diff --git a/src/http.cc b/src/http.cc index 8746f5a8a8..92ef70f47e 100644 --- a/src/http.cc +++ b/src/http.cc @@ -58,6 +58,7 @@ #include "http.h" #include "HttpControlMsg.h" #include "HttpHdrContRange.h" +#include "HttpHdrCc.h" #include "HttpHdrSc.h" #include "HttpHdrScTarget.h" #include "HttpReply.h" diff --git a/src/mem.cc b/src/mem.cc index 408052647a..e6bd2b1f0c 100644 --- a/src/mem.cc +++ b/src/mem.cc @@ -453,7 +453,6 @@ Mem::Init(void) memDataInit(MEM_DLINK_NODE, "dlink_node", sizeof(dlink_node), 10); memDataInit(MEM_DREAD_CTRL, "dread_ctrl", sizeof(dread_ctrl), 0); memDataInit(MEM_DWRITE_Q, "dwrite_q", sizeof(dwrite_q), 0); - memDataInit(MEM_HTTP_HDR_CC, "HttpHdrCc", sizeof(HttpHdrCc), 0); memDataInit(MEM_HTTP_HDR_CONTENT_RANGE, "HttpHdrContRange", sizeof(HttpHdrContRange), 0); memDataInit(MEM_NETDBENTRY, "netdbEntry", sizeof(netdbEntry), 0); memDataInit(MEM_NET_DB_NAME, "net_db_name", sizeof(net_db_name), 0); diff --git a/src/mime.cc b/src/mime.cc index 0fd978dd80..1d8c4b485b 100644 --- a/src/mime.cc +++ b/src/mime.cc @@ -34,6 +34,7 @@ */ #include "squid.h" +#include "HttpHdrCc.h" #include "Store.h" #include "StoreClient.h" #include "HttpReply.h" diff --git a/src/refresh.cc b/src/refresh.cc index d16915a401..af6acafb57 100644 --- a/src/refresh.cc +++ b/src/refresh.cc @@ -38,6 +38,7 @@ #endif #include "squid.h" +#include "HttpHdrCc.h" #include "mgr/Registration.h" #include "Store.h" #include "MemObject.h"