Amos Jeffries wrote:
Port of the hier_code ACL from 2.7.

This goes a little further than a straight port by adding Henriks suggestion of a numeric-based array of codes. Instead of a string-wise search on every use it's a speedy boolean array seek on use and a slow array seek+match on configure.

If there are no objections I'd like to merge it in a few days.


The code would probably help. ;)

Amos
--
Please be using
  Current Stable Squid 2.7.STABLE6 or 3.0.STABLE18
  Current Beta Squid 3.1.0.13
=== modified file 'src/AclRegs.cc'
--- src/AclRegs.cc	2009-06-01 12:31:43 +0000
+++ src/AclRegs.cc	2009-08-07 14:45:55 +0000
@@ -20,6 +20,8 @@
 #include "acl/ExtUser.h"
 #include "acl/FilledChecklist.h"
 #include "acl/Gadgets.h"
+#include "acl/HierCodeData.h"
+#include "acl/HierCode.h"
 #include "acl/HttpHeaderData.h"
 #include "acl/HttpRepHeader.h"
 #include "acl/HttpReqHeader.h"
@@ -79,6 +81,8 @@
 ACLExtUser ACLExtUser::UserRegistryEntry_(new ACLUserData, "ext_user");
 ACL::Prototype ACLExtUser::RegexRegistryProtoype(&ACLExtUser::RegexRegistryEntry_, "ext_user_regex" );
 ACLExtUser ACLExtUser::RegexRegistryEntry_(new ACLRegexData, "ext_user_regex");
+ACL::Prototype ACLHierCode::RegistryProtoype(&ACLHierCode::RegistryEntry_, "hier_code");
+ACLStrategised<hier_code> ACLHierCode::RegistryEntry_(new ACLHierCodeData, ACLHierCodeStrategy::Instance(), "hier_code");
 ACL::Prototype ACLHTTPRepHeader::RegistryProtoype(&ACLHTTPRepHeader::RegistryEntry_, "rep_header");
 ACLStrategised<HttpHeader*> ACLHTTPRepHeader::RegistryEntry_(new ACLHTTPHeaderData, ACLHTTPRepHeaderStrategy::Instance(), "rep_header");
 ACL::Prototype ACLHTTPReqHeader::RegistryProtoype(&ACLHTTPReqHeader::RegistryEntry_, "req_header");

=== modified file 'src/HierarchyLogEntry.h'
--- src/HierarchyLogEntry.h	2009-07-12 22:56:47 +0000
+++ src/HierarchyLogEntry.h	2009-08-14 08:14:41 +0000
@@ -34,10 +34,11 @@
 #ifndef SQUID_HTTPHIERARCHYLOGENTRY_H
 #define SQUID_HTTPHIERARCHYLOGENTRY_H
 
+#include "hier_code.h"
 #include "rfc2181.h"
 #include "PingData.h"
 
-/** todo Cleanup: break hier_code type out. We don't need the rest. */
+/* for lookup_t and http_status */
 #include "enums.h"
 
 class HierarchyLogEntry

=== modified file 'src/Makefile.am'
--- src/Makefile.am	2009-07-26 09:24:07 +0000
+++ src/Makefile.am	2009-08-14 05:47:57 +0000
@@ -354,6 +354,8 @@
 	gopher.cc \
 	helper.cc \
 	helper.h \
+	hier_code.h \
+	hier_code.cc \
 	HierarchyLogEntry.h \
 	$(HTCPSOURCE) \
 	http.cc \
@@ -1088,6 +1090,8 @@
 	fqdncache.cc \
 	ftp.cc \
 	gopher.cc \
+	hier_code.h \
+	hier_code.cc \
 	helper.cc \
 	$(HTCPSOURCE) \
 	http.cc \
@@ -1258,6 +1262,8 @@
 	fqdncache.cc \
 	ftp.cc \
 	gopher.cc \
+	hier_code.h \
+	hier_code.cc \
 	helper.cc \
 	$(HTCPSOURCE) \
 	http.cc \
@@ -1407,6 +1413,8 @@
 	ftp.cc \
 	gopher.cc \
 	helper.cc \
+	hier_code.h \
+	hier_code.cc \
 	$(HTCPSOURCE) \
 	http.cc \
 	HttpBody.cc \
@@ -1544,6 +1552,8 @@
 	ftp.cc \
 	gopher.cc \
 	helper.cc \
+	hier_code.h \
+	hier_code.cc \
 	$(HTCPSOURCE) \
 	http.cc \
 	HttpBody.cc \
@@ -1697,6 +1707,8 @@
 	ftp.cc \
 	gopher.cc \
 	helper.cc \
+	hier_code.h \
+	hier_code.cc \
 	$(HTCPSOURCE) \
 	http.cc \
 	HttpBody.cc \
@@ -2049,6 +2061,8 @@
 	ftp.cc \
 	gopher.cc \
 	helper.cc \
+	hier_code.h \
+	hier_code.cc \
 	$(HTCPSOURCE) \
 	http.cc \
 	HttpBody.cc \

=== modified file 'src/access_log.cc'
--- src/access_log.cc	2009-07-12 22:56:47 +0000
+++ src/access_log.cc	2009-08-07 14:48:46 +0000
@@ -41,6 +41,7 @@
 
 #include "acl/Checklist.h"
 
+#include "hier_code.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
 #include "MemBuf.h"

=== added file 'src/acl/HierCode.cc'
--- src/acl/HierCode.cc	1970-01-01 00:00:00 +0000
+++ src/acl/HierCode.cc	2009-08-07 14:45:09 +0000
@@ -0,0 +1,24 @@
+#include "squid.h"
+#include "acl/HierCode.h"
+#include "acl/HierCodeData.h"
+#include "acl/Checklist.h"
+#include "HttpRequest.h"
+
+/* explicit template instantiation required for some systems */
+
+template class ACLStrategised<hier_code>;
+
+
+int
+ACLHierCodeStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
+{
+    return data->match (checklist->request->hier.code);
+}
+
+ACLHierCodeStrategy *
+ACLHierCodeStrategy::Instance()
+{
+    return &Instance_;
+}
+
+ACLHierCodeStrategy ACLHierCodeStrategy::Instance_;

=== added file 'src/acl/HierCode.h'
--- src/acl/HierCode.h	1970-01-01 00:00:00 +0000
+++ src/acl/HierCode.h	2009-08-07 14:45:09 +0000
@@ -0,0 +1,42 @@
+#ifndef SQUID_ACLHIERCODE_H
+#define SQUID_ACLHIERCODE_H
+
+#include "acl/Strategy.h"
+#include "acl/Strategised.h"
+#include "hier_code.h"
+
+/// \ingroup ACLAPI
+class ACLHierCodeStrategy : public ACLStrategy<hier_code>
+{
+
+public:
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
+    virtual bool requiresRequest() const {return true;}
+
+    static ACLHierCodeStrategy *Instance();
+
+    /**
+     * Not implemented to prevent copies of the instance.
+     \par
+     * Not private to prevent brain dead g+++ warnings about
+     * private constructors with no friends
+     */
+    ACLHierCodeStrategy(ACLHierCodeStrategy const &);
+
+private:
+    static ACLHierCodeStrategy Instance_;
+    ACLHierCodeStrategy() {}
+
+    ACLHierCodeStrategy &operator=(ACLHierCodeStrategy const &);
+};
+
+/// \ingroup ACLAPI
+class ACLHierCode
+{
+
+private:
+    static ACL::Prototype RegistryProtoype;
+    static ACLStrategised<hier_code> RegistryEntry_;
+};
+
+#endif /* SQUID_ACLHIERCODE_H */

=== added file 'src/acl/HierCodeData.cc'
--- src/acl/HierCodeData.cc	1970-01-01 00:00:00 +0000
+++ src/acl/HierCodeData.cc	2009-08-10 09:22:57 +0000
@@ -0,0 +1,72 @@
+#include "squid.h"
+#include "acl/HierCodeData.h"
+#include "acl/Checklist.h"
+#include "hier_code.h"
+#include "wordlist.h"
+
+ACLHierCodeData::ACLHierCodeData()
+{
+    // initialize mask to NULL
+    memset(values, 0, sizeof(values));
+}
+
+ACLHierCodeData::ACLHierCodeData(ACLHierCodeData const &old)
+{
+    memcpy(values, old.values, sizeof(values) );
+}
+
+ACLHierCodeData::~ACLHierCodeData()
+{ }
+
+bool
+ACLHierCodeData::match(hier_code toFind)
+{
+    return values[toFind];
+}
+
+wordlist *
+ACLHierCodeData::dump()
+{
+    wordlist *W = NULL;
+
+    for (hier_code iter=HIER_NONE; iter<HIER_MAX; ++iter) {
+        if (!values[iter]) continue;
+        wordlistAdd(&W, hier_strings[iter]);
+    }
+
+    return W;
+}
+
+void
+ACLHierCodeData::parse()
+{
+    char *t = NULL;
+
+    while ((t = strtokFile())) {
+        for (hier_code iter = HIER_NONE; iter <= HIER_MAX; ++iter) {
+            if (iter == HIER_MAX) {
+                fatalf("ERROR: No such hier_code '%s'",t);
+                return;
+            }
+            if (strcmp(hier_strings[iter],t) == 0) {
+                values[iter] = true;
+                break; // back to while-loop
+            }
+        }
+    }
+}
+
+bool
+ACLHierCodeData::empty() const
+{
+    for (hier_code iter = HIER_NONE; iter <= HIER_MAX; ++iter) {
+        if (values[iter]) return false; // not empty.
+    }
+    return true;
+}
+
+ACLData<hier_code> *
+ACLHierCodeData::clone() const
+{
+    return new ACLHierCodeData(*this);
+}

=== added file 'src/acl/HierCodeData.h'
--- src/acl/HierCodeData.h	1970-01-01 00:00:00 +0000
+++ src/acl/HierCodeData.h	2009-08-07 14:58:20 +0000
@@ -0,0 +1,32 @@
+#ifndef SQUID_ACLHIERCODEDATA_H
+#define SQUID_ACLHIERCODEDATA_H
+
+#include "acl/Acl.h"
+#include "acl/Data.h"
+#include "CbDataList.h"
+#include "hier_code.h"
+
+/// \ingroup ACLAPI
+class ACLHierCodeData : public ACLData<hier_code>
+{
+
+public:
+    MEMPROXY_CLASS(ACLHierCodeData);
+
+    ACLHierCodeData();
+    ACLHierCodeData(ACLHierCodeData const &);
+    ACLHierCodeData &operator= (ACLHierCodeData const &);
+    virtual ~ACLHierCodeData();
+    bool match(hier_code);
+    wordlist *dump();
+    void parse();
+    bool empty() const;
+    virtual ACLData<hier_code> *clone() const;
+
+    // mask of codes this ACL might match.
+    bool values[HIER_MAX];
+};
+
+MEMPROXY_CLASS_INLINE(ACLHierCodeData);
+
+#endif /* SQUID_ACLHIERCODEDATA_H */

=== modified file 'src/acl/Makefile.am'
--- src/acl/Makefile.am	2009-06-01 12:31:43 +0000
+++ src/acl/Makefile.am	2009-08-07 14:45:09 +0000
@@ -47,6 +47,10 @@
 	DomainData.h \
 	ExtUser.cc \
 	ExtUser.h \
+	HierCodeData.cc \
+	HierCodeData.h \
+	HierCode.cc \
+	HierCode.h \
 	HttpHeaderData.cc \
 	HttpHeaderData.h \
 	HttpRepHeader.cc \

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2009-08-07 12:44:51 +0000
+++ src/cf.data.pre	2009-08-07 15:11:05 +0000
@@ -677,6 +677,14 @@
 	acl aclname tag tagvalue ...
 	  # string match on tag returned by external acl helper [slow]
 
+	acl acl_name hier_code codename ...
+	  # string match against squid hierarchy code(s); [fast]
+	  #  e.g., DIRECT, PARENT_HIT, NONE, etc.
+	  #
+	  # NOTE: This has no effect in http_access rules. It only has
+	  # effect in rules that affect the reply data stream such as
+	  # http_reply_access.
+
 Examples:
 acl macaddress arp 09:00:2b:23:45:67
 acl myexample dst_as 1241

=== modified file 'src/enums.h'
--- src/enums.h	2009-08-03 10:17:22 +0000
+++ src/enums.h	2009-08-07 14:45:09 +0000
@@ -155,32 +155,6 @@
     SC_ENUM_END
 } http_hdr_sc_type;
 
-typedef enum {
-    HIER_NONE,
-    HIER_DIRECT,
-    SIBLING_HIT,
-    PARENT_HIT,
-    DEFAULT_PARENT,
-    SINGLE_PARENT,
-    FIRSTUP_PARENT,
-    FIRST_PARENT_MISS,
-    CLOSEST_PARENT_MISS,
-    CLOSEST_PARENT,
-    CLOSEST_DIRECT,
-    NO_DIRECT_FAIL,
-    SOURCE_FASTEST,
-    ROUNDROBIN_PARENT,
-#if USE_CACHE_DIGESTS
-    CD_PARENT_HIT,
-    CD_SIBLING_HIT,
-#endif
-    CARP,
-    ANY_OLD_PARENT,
-    USERHASH_PARENT,
-    SOURCEHASH_PARENT,
-    HIER_MAX,
-    PINNED
-} hier_code;
 
 /// \ingroup ServerProtocolICPAPI
 typedef enum {

=== modified file 'src/forward.cc'
--- src/forward.cc	2009-07-12 22:56:47 +0000
+++ src/forward.cc	2009-08-12 09:47:11 +0000
@@ -39,6 +39,7 @@
 #include "event.h"
 #include "errorpage.h"
 #include "fde.h"
+#include "hier_code.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
 #include "MemObject.h"

=== modified file 'src/forward.h'
--- src/forward.h	2009-07-12 22:56:47 +0000
+++ src/forward.h	2009-08-10 09:55:06 +0000
@@ -7,11 +7,11 @@
 class HttpRequest;
 
 #include "comm.h"
+#include "hier_code.h"
 #include "ip/IpAddress.h"
 
 class FwdServer
 {
-
 public:
     peer *_peer;                /* NULL --> origin server */
     hier_code code;
@@ -20,7 +20,6 @@
 
 class FwdState : public RefCountable
 {
-
 public:
     typedef RefCount<FwdState> Pointer;
     ~FwdState();

=== added file 'src/hier_code.cc'
--- src/hier_code.cc	1970-01-01 00:00:00 +0000
+++ src/hier_code.cc	2009-08-07 14:53:09 +0000
@@ -0,0 +1,29 @@
+#include "config.h"
+#include "hier_code.h"
+
+const char *hier_strings[] = {
+    "NONE",          /* HIER_NONE */
+    "DIRECT",        /* HIER_DIRECT */
+    "SIBLING_HIT",
+    "PARENT_HIT",
+    "DEFAULT_PARENT",
+    "SINGLE_PARENT",
+    "FIRSTUP_PARENT",
+    "FIRST_PARENT_MISS",
+    "CLOSEST_PARENT_MISS",
+    "CLOSEST_PARENT",
+    "CLOSEST_DIRECT",
+    "NO_DIRECT_FAIL",
+    "SOURCE_FASTEST",
+    "ROUNDROBIN_PARENT",
+#if USE_CACHE_DIGESTS
+    "CD_PARENT_HIT",
+    "CD_SIBLING_HIT",
+#endif
+    "CARP",
+    "ANY_PARENT",
+    "USERHASH",
+    "SOURCEHASH",
+    "PINNED",
+    "HIER_MAX"
+};

=== added file 'src/hier_code.h'
--- src/hier_code.h	1970-01-01 00:00:00 +0000
+++ src/hier_code.h	2009-08-10 11:41:28 +0000
@@ -0,0 +1,35 @@
+#ifndef SQUID__HIER_CODE_H
+#define SQUID__HIER_CODE_H
+
+typedef enum {
+    HIER_NONE,
+    HIER_DIRECT,
+    SIBLING_HIT,
+    PARENT_HIT,
+    DEFAULT_PARENT,
+    SINGLE_PARENT,
+    FIRSTUP_PARENT,
+    FIRST_PARENT_MISS,
+    CLOSEST_PARENT_MISS,
+    CLOSEST_PARENT,
+    CLOSEST_DIRECT,
+    NO_DIRECT_FAIL,
+    SOURCE_FASTEST,
+    ROUNDROBIN_PARENT,
+#if USE_CACHE_DIGESTS
+    CD_PARENT_HIT,
+    CD_SIBLING_HIT,
+#endif
+    CARP,
+    ANY_OLD_PARENT,
+    USERHASH_PARENT,
+    SOURCEHASH_PARENT,
+    PINNED,
+    HIER_MAX
+} hier_code;
+
+extern const char *hier_strings[];
+
+inline const hier_code operator++(hier_code &i) { return (hier_code)(i+1); }
+
+#endif /* SQUID__HIER_CODE_H */

=== modified file 'src/peer_select.cc'
--- src/peer_select.cc	2009-07-12 08:58:47 +0000
+++ src/peer_select.cc	2009-08-10 10:10:16 +0000
@@ -36,6 +36,7 @@
 #include "event.h"
 #include "PeerSelectState.h"
 #include "Store.h"
+#include "hier_code.h"
 #include "ICP.h"
 #include "HttpRequest.h"
 #include "acl/FilledChecklist.h"
@@ -44,32 +45,6 @@
 #include "SquidTime.h"
 #include "icmp/net_db.h"
 
-const char *hier_strings[] = {
-    "NONE",
-    "DIRECT",
-    "SIBLING_HIT",
-    "PARENT_HIT",
-    "DEFAULT_PARENT",
-    "SINGLE_PARENT",
-    "FIRST_UP_PARENT",
-    "FIRST_PARENT_MISS",
-    "CLOSEST_PARENT_MISS",
-    "CLOSEST_PARENT",
-    "CLOSEST_DIRECT",
-    "NO_DIRECT_FAIL",
-    "SOURCE_FASTEST",
-    "ROUNDROBIN_PARENT",
-#if USE_CACHE_DIGESTS
-    "CD_PARENT_HIT",
-    "CD_SIBLING_HIT",
-#endif
-    "CARP",
-    "ANY_PARENT",
-    "USERHASH",
-    "SOURCEHASH",
-    "INVALID CODE"
-};
-
 static struct {
     int timeouts;
 } PeerStats;
@@ -624,7 +599,6 @@
 peerSelectInit(void)
 {
     memset(&PeerStats, '\0', sizeof(PeerStats));
-    assert(sizeof(hier_strings) == (HIER_MAX + 1) * sizeof(char *));
 }
 
 static void

Reply via email to