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 <a.samirh78@gmail.com>bb10
parent
eeb6f0337e
commit
7200f8638c
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue