From 7200f8638ca76ce6b8c57128e7a0b0fe9a732c4f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 13 May 2024 16:04:25 -0700 Subject: [PATCH] QByteArray: deduplicate QtPrivate::findByteArray() and qFindByteArray() The former is the only place where the latter is called and both were doing duplicate and redudant work. So merge the two functions again... and split off the actual hashed searching into a new qFindByteArray. That simplifies the diff and Git history. Drive-by adding the Q_NEVER_INLINE to the Boyer-Moore search, which will be reached via tail-call. Task-number: QTBUG-125283 Change-Id: If05cb740b64f42eba21efffd17cf2ed2bbc64b17 Reviewed-by: Ahmad Samir --- src/corelib/text/qbytearray.cpp | 24 ------------------------ src/corelib/text/qbytearraymatcher.cpp | 24 +++++++++++++++--------- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp index e6387e4bed..ece12892ac 100644 --- a/src/corelib/text/qbytearray.cpp +++ b/src/corelib/text/qbytearray.cpp @@ -56,10 +56,6 @@ static constexpr inline uchar asciiLower(uchar c) return c >= 'A' && c <= 'Z' ? c | 0x20 : c; } -qsizetype qFindByteArray( - const char *haystack0, qsizetype haystackLen, qsizetype from, - const char *needle0, qsizetype needleLen); - /***************************************************************************** Safe and portable C string functions; extensions to standard string.h *****************************************************************************/ @@ -2685,26 +2681,6 @@ QByteArray QByteArray::repeated(qsizetype times) const hashHaystack -= std::size_t(a) << ol_minus_1; \ hashHaystack <<= 1 -qsizetype QtPrivate::findByteArray(QByteArrayView haystack, qsizetype from, QByteArrayView needle) noexcept -{ - const auto ol = needle.size(); - const auto l = haystack.size(); - if (ol == 0) { - if (from < 0) - return qMax(from + l, 0); - else - return from > l ? -1 : from; - } - - if (ol == 1) - return findByteArray(haystack, from, needle.front()); - - if (from > l || ol + from > l) - return -1; - - return qFindByteArray(haystack.data(), haystack.size(), from, needle.data(), ol); -} - /*! \fn qsizetype QByteArray::indexOf(QByteArrayView bv, qsizetype from) const \since 6.0 diff --git a/src/corelib/text/qbytearraymatcher.cpp b/src/corelib/text/qbytearraymatcher.cpp index 411766c46e..b3e38d53e4 100644 --- a/src/corelib/text/qbytearraymatcher.cpp +++ b/src/corelib/text/qbytearraymatcher.cpp @@ -215,6 +215,7 @@ qsizetype QByteArrayMatcher::indexIn(QByteArrayView data, qsizetype from) const /*! \internal */ +Q_NEVER_INLINE static qsizetype qFindByteArrayBoyerMoore( const char *haystack, qsizetype haystackLen, qsizetype haystackOffset, const char *needle, qsizetype needleLen) @@ -235,12 +236,13 @@ static qsizetype qFindByteArrayBoyerMoore( /*! \internal */ -qsizetype qFindByteArray( - const char *haystack0, qsizetype haystackLen, qsizetype from, - const char *needle, qsizetype needleLen) +static qsizetype qFindByteArray(const char *haystack0, qsizetype l, qsizetype from, + const char *needle, qsizetype sl); +qsizetype QtPrivate::findByteArray(QByteArrayView haystack, qsizetype from, QByteArrayView needle) noexcept { - const auto l = haystackLen; - const auto sl = needleLen; + const auto haystack0 = haystack.data(); + const auto l = haystack.size(); + const auto sl = needle.size(); if (from < 0) from += l; if (std::size_t(sl + from) > std::size_t(l)) @@ -251,7 +253,7 @@ qsizetype qFindByteArray( return -1; if (sl == 1) - return QtPrivate::findByteArray({ haystack0, haystackLen }, from, needle[0]); + return findByteArray(haystack, from, needle.front()); /* We use the Boyer-Moore algorithm in cases where the overhead @@ -259,13 +261,17 @@ qsizetype qFindByteArray( hash function. */ if (l > 500 && sl > 5) - return qFindByteArrayBoyerMoore(haystack0, haystackLen, from, - needle, needleLen); + return qFindByteArrayBoyerMoore(haystack0, l, from, needle.data(), sl); + return qFindByteArray(haystack0, l, from, needle.data(), sl); +} +qsizetype qFindByteArray(const char *haystack0, qsizetype l, qsizetype from, + const char *needle, qsizetype sl) +{ /* We use some hashing for efficiency's sake. Instead of comparing strings, we compare the hash value of str with that - of a part of this QString. Only if that matches, we call memcmp(). + of a part of this QByteArray. Only if that matches, we call memcmp(). */ const char *haystack = haystack0 + from; const char *end = haystack0 + (l - sl);