Hi all,
  here's the updated patch.

Thanks

On Tue, Dec 17, 2013 at 6:04 PM, Kinkie <[email protected]> wrote:
> On Tue, Dec 17, 2013 at 6:06 AM, Alex Rousskov
> <[email protected]> wrote:
>> On 12/16/2013 03:36 PM, Alex Rousskov wrote:
>>>> Rewrite the += operator loop to simply
>>>> this->add() every character in the src set. Use std::for_each or another
>>>> <algorithm> for that if possible.
>>
>>> I think the above is still valid though.
>>
>> but I cannot find a suitable algorithm. If you cannot either, just use
>> add() calls in an explicit loop.
>
> std::copy_if is perfect for the job; using that.
>
> --
>     /kinkie



-- 
    /kinkie
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: [email protected]
# target_branch: ../trunk
# testament_sha1: a0f01e9f4dba9b1740a76f8a55b1848fd69897e7
# timestamp: 2013-12-17 18:29:03 +0100
# base_revision_id: [email protected]\
#   oxujawxqsudye9eh
# 
# Begin patch
=== modified file 'src/Makefile.am'
--- src/Makefile.am	2013-12-12 09:41:39 +0000
+++ src/Makefile.am	2013-12-17 17:05:17 +0000
@@ -15,6 +15,7 @@
 	DnsLookupDetails.cc
 
 SBUF_SOURCE= \
+	base/CharacterSet.h \
 	base/InstanceId.h \
 	MemBlob.h \
 	MemBlob.cc \

=== modified file 'src/SBuf.cc'
--- src/SBuf.cc	2013-11-27 15:52:03 +0000
+++ src/SBuf.cc	2013-12-17 10:19:44 +0000
@@ -27,6 +27,7 @@
  */
 
 #include "squid.h"
+#include "base/CharacterSet.h"
 #include "base/RefCount.h"
 #include "Debug.h"
 #include "OutOfBoundsException.h"
@@ -688,28 +689,45 @@
 }
 
 SBuf::size_type
-SBuf::find_first_of(const SBuf &set, size_type startPos) const
-{
-    // if set is 1 char big, use the char search. Stats updated there
-    if (set.length() == 1)
-        return find(set[0], startPos);
-
-    ++stats.find;
-
-    if (startPos == npos)
-        return npos;
-
-    if (startPos >= length())
-        return npos;
-
-    if (set.length() == 0)
-        return npos;
-
-    debugs(24, 7, "any of '" << set << "' " << " in id " << id);
-    char *cur = buf()+startPos, *end = bufEnd();
-    while (cur < end) {
-        if (memchr(set.buf(), *cur, set.length()))
-            return (cur-buf());
+SBuf::find_first_of(const CharacterSet &set, size_type startPos) const
+{
+    ++stats.find;
+
+    if (startPos == npos)
+        return npos;
+
+    if (startPos >= length())
+        return npos;
+
+    debugs(24, 7, "first of characterset " << set.name << " in id " << id);
+    char *cur = buf()+startPos;
+    const char *end = bufEnd();
+    while (cur < end) {
+        if (set[*cur])
+            return cur-buf();
+        ++cur;
+    }
+    debugs(24, 7, "not found");
+    return npos;
+}
+
+SBuf::size_type
+SBuf::find_first_not_of(const CharacterSet &set, size_type startPos) const
+{
+    ++stats.find;
+
+    if (startPos == npos)
+        return npos;
+
+    if (startPos >= length())
+        return npos;
+
+    debugs(24, 7, "first not of characterset " << set.name << " in id " << id);
+    char *cur = buf()+startPos;
+    const char *end = bufEnd();
+    while (cur < end) {
+        if (!set[*cur])
+            return cur-buf();
         ++cur;
     }
     debugs(24, 7, "not found");

=== modified file 'src/SBuf.h'
--- src/SBuf.h	2013-12-04 18:37:08 +0000
+++ src/SBuf.h	2013-12-17 10:19:44 +0000
@@ -101,6 +101,8 @@
     SBufStats& operator +=(const SBufStats&);
 };
 
+class CharacterSet;
+
 /**
  * A String or Buffer.
  * Features: refcounted backing store, cheap copy and sub-stringing
@@ -512,8 +514,20 @@
      * \return npos if no character in the set could be found
      * \param startPos if specified, ignore any occurrences before that position
      *   if npos, then npos is always returned
-     */
-    size_type find_first_of(const SBuf &set, size_type startPos = 0) const;
+     *
+     * TODO: rename to camelCase
+     */
+    size_type find_first_of(const CharacterSet &set, size_type startPos = 0) const;
+
+    /** Find first occurrence character NOT in character set
+     *
+     * \return npos if all characters in the SBuf are from set
+     * \param startPos if specified, ignore any occurrences before that position
+     *   if npos, then npos is always returned
+     *
+     * TODO: rename to camelCase
+     */
+    size_type find_first_not_of(const CharacterSet &set, size_type startPos = 0) const;
 
     /** sscanf-alike
      *

=== added file 'src/base/CharacterSet.cc'
--- src/base/CharacterSet.cc	1970-01-01 00:00:00 +0000
+++ src/base/CharacterSet.cc	2013-12-17 17:02:51 +0000
@@ -0,0 +1,32 @@
+#include "squid.h"
+
+#include "CharacterSet.h"
+
+#include <algorithm>
+
+static bool
+isNonZero(uint8_t i) {
+    return i!=0;
+}
+
+const CharacterSet &
+CharacterSet::operator +=(const CharacterSet &src)
+{
+    std::copy_if(src.chars_.begin(),src.chars_.end(),chars_.begin(),isNonZero);
+    return *this;
+}
+
+CharacterSet &
+CharacterSet::add(const unsigned char c)
+{
+    chars_[static_cast<uint8_t>(c)] = 1;
+    return *this;
+}
+
+CharacterSet::CharacterSet(const char *label, const char * const c)
+: name(label == NULL ? "anonymous" : label), chars_(vector_type(256,0))
+{
+    const size_t clen = strlen(c);
+    for (size_t i = 0; i < clen; ++i)
+        add(c[i]);
+}

=== added file 'src/base/CharacterSet.h'
--- src/base/CharacterSet.h	1970-01-01 00:00:00 +0000
+++ src/base/CharacterSet.h	2013-12-17 17:28:53 +0000
@@ -0,0 +1,38 @@
+#ifndef _SQUID_SRC_PARSER_CHARACTERSET_H
+#define _SQUID_SRC_PARSER_CHARACTERSET_H
+
+#include <vector>
+
+/// Optimized set of C chars, with quick membership test and merge support
+class CharacterSet
+{
+public:
+    typedef std::vector<uint8_t> vector_type;
+
+    /// define a character set with the given label ("anonymous" if NULL,
+    ///  with specified initial contents
+    CharacterSet(const char *label, const char * const initial);
+
+    /// whether a given character exists in the set
+    bool operator[](unsigned char c) const {return chars_[static_cast<uint8_t>(c)] == 1;}
+
+    /// add a given character to the character set.
+    CharacterSet & add(const unsigned char c);
+
+    /// add all characters from the given CharacterSet to this one
+    const CharacterSet &operator +=(const CharacterSet &src);
+
+    /// optional set label for debugging (default: "anonymous")
+    const char * name;
+
+private:
+    /** characters present in this set.
+     *
+     * \note guaranteed to be always 256 slots big, as forced in the
+     *  constructor. This assumption is relied upon in operator[], add,
+     *  operator+=
+     */
+   vector_type chars_;
+};
+
+#endif /* _SQUID_SRC_PARSER_CHARACTERSET_H */

=== modified file 'src/base/Makefile.am'
--- src/base/Makefile.am	2013-11-26 09:43:29 +0000
+++ src/base/Makefile.am	2013-12-17 10:19:44 +0000
@@ -12,6 +12,8 @@
 	AsyncJobCalls.h \
 	AsyncCallQueue.cc \
 	AsyncCallQueue.h \
+	CharacterSet.h \
+	CharacterSet.cc \
 	TidyPointer.h \
 	CbcPointer.h \
 	InstanceId.h \

=== modified file 'src/icmp/Makefile.am'
--- src/icmp/Makefile.am	2013-12-03 07:49:13 +0000
+++ src/icmp/Makefile.am	2013-12-15 11:47:07 +0000
@@ -23,6 +23,7 @@
 noinst_LTLIBRARIES = libicmp-core.la libicmp.la
 
 SBUF_SOURCE= \
+	$(top_srcdir)/src/base/CharacterSet.h \
 	$(top_srcdir)/src/SBuf.h \
 	$(top_srcdir)/src/SBuf.cc \
 	$(top_srcdir)/src/MemBlob.h \

=== modified file 'src/tests/SBufFindTest.cc'
--- src/tests/SBufFindTest.cc	2013-11-11 12:06:11 +0000
+++ src/tests/SBufFindTest.cc	2013-12-15 12:48:01 +0000
@@ -1,4 +1,5 @@
 #include "squid.h"
+#include "base/CharacterSet.h"
 #include "SBufFindTest.h"
 #include <cppunit/extensions/HelperMacros.h>
 #include <cppunit/Message.h>
@@ -105,7 +106,7 @@
 {
     theFindString = theStringHay.find_first_of(theStringNeedle, thePos);
     theBareNeedlePos = theStringHay.find_first_of(theStringNeedle);
-    theFindSBuf = theSBufHay.find_first_of(theSBufNeedle, thePos);
+    theFindSBuf = theSBufHay.find_first_of(CharacterSet("cs",theSBufNeedle.c_str()), thePos);
     checkResults("find_first_of");
 }
 

=== modified file 'src/tests/testSBuf.cc'
--- src/tests/testSBuf.cc	2013-11-27 15:52:03 +0000
+++ src/tests/testSBuf.cc	2013-12-17 10:19:44 +0000
@@ -1,4 +1,5 @@
 #include "squid.h"
+#include "base/CharacterSet.h"
 #include "Mem.h"
 #include "SBuf.h"
 #include "SBufFindTest.h"
@@ -759,23 +760,47 @@
     SBuf::size_type idx;
 
     // not found
-    idx=haystack.find_first_of(SBuf("ADHRWYP"));
+    idx=haystack.find_first_of(CharacterSet("t1","ADHRWYP"));
     CPPUNIT_ASSERT_EQUAL(SBuf::npos,idx);
 
     // found at beginning
-    idx=haystack.find_first_of(SBuf("THANDF"));
+    idx=haystack.find_first_of(CharacterSet("t2","THANDF"));
     CPPUNIT_ASSERT_EQUAL(0U,idx);
 
     //found at end of haystack
-    idx=haystack.find_first_of(SBuf("QWERYVg"));
+    idx=haystack.find_first_of(CharacterSet("t3","QWERYVg"));
     CPPUNIT_ASSERT_EQUAL(haystack.length()-1,idx);
 
     //found in the middle of haystack
-    idx=haystack.find_first_of(SBuf("QWERqYV"));
+    idx=haystack.find_first_of(CharacterSet("t4","QWERqYV"));
     CPPUNIT_ASSERT_EQUAL(4U,idx);
 }
 
 void
+testSBuf::testFindFirstNotOf()
+{
+    SBuf haystack(literal);
+    SBuf::size_type idx;
+
+    // all chars from the set
+    idx=haystack.find_first_not_of(CharacterSet("t1",literal.c_str()));
+    CPPUNIT_ASSERT_EQUAL(SBuf::npos,idx);
+
+    // found at beginning
+    idx=haystack.find_first_not_of(CharacterSet("t2","a"));
+    CPPUNIT_ASSERT_EQUAL(0U,idx);
+
+    //found at end of haystack
+    idx=haystack.find_first_not_of(CharacterSet("t3",literal.substr(0,literal.length()-1).c_str()));
+    CPPUNIT_ASSERT_EQUAL(haystack.length()-1,idx);
+
+    //found in the middle of haystack
+    idx=haystack.find_first_not_of(CharacterSet("t4","The"));
+    CPPUNIT_ASSERT_EQUAL(3U,idx);
+}
+
+
+void
 testSBuf::testAutoFind()
 {
     SBufFindTest test;

=== modified file 'src/tests/testSBuf.h'
--- src/tests/testSBuf.h	2013-07-26 09:20:09 +0000
+++ src/tests/testSBuf.h	2013-12-15 11:47:07 +0000
@@ -35,6 +35,7 @@
     CPPUNIT_TEST( testRFindChar );
     CPPUNIT_TEST( testRFindSBuf );
     CPPUNIT_TEST( testFindFirstOf );
+    CPPUNIT_TEST( testFindFirstNotOf );
     CPPUNIT_TEST( testPrintf );
     CPPUNIT_TEST( testScanf );
     CPPUNIT_TEST( testCopy );
@@ -79,6 +80,7 @@
     void testStartsWith();
     void testSBufStream();
     void testFindFirstOf();
+    void testFindFirstNotOf();
     void testAutoFind();
     void testStdStringOps();
 };

# Begin bundle
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

Reply via email to