use libdeflate_crc32() for hashing

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-04-27 03:05:03 +03:00
parent d27075599e
commit facd387374
10 changed files with 22 additions and 126 deletions

View file

@ -11,7 +11,6 @@ set(unifdef_arguments
-UQT_BOOTSTRAPPED
# not supported
-UQT_NO_QOBJECT
-UQT_NO_COMPRESS
-UQT_NO_THREAD
-UQT_NO_PROCESS
-UQT_NO_DATASTREAM

View file

@ -46,7 +46,6 @@
// Not supported, used to bootstrap
#cmakedefine QT_NO_QOBJECT
#cmakedefine QT_NO_COMPRESS
#cmakedefine QT_NO_THREAD
#cmakedefine QT_NO_PROCESS
#cmakedefine QT_NO_DATASTREAM

View file

@ -150,7 +150,7 @@ static inline QByteArray normalizeTypeInternal(const char *t, const char *e, boo
{
const int len = e - t;
#ifndef QT_BOOTSTRAPPED
const uint cachekey = qHash(QByteArray::fromRawData(t, len));
const uint cachekey = qHash(t, len);
QMutexLocker lock(qGlobalNormalizedTypeMutex());
QByteArray cached = qGlobalNormalizedTypeHash()->value(cachekey);
if (!cached.isEmpty()) {

View file

@ -35,9 +35,7 @@
#include <string.h>
#include <stdlib.h>
#ifndef QT_NO_COMPRESS
#include <libdeflate.h>
#endif // QT_NO_COMPRESS
#define IS_RAW_DATA(d) ((d)->data != (d)->array)
@ -223,21 +221,6 @@ char* qstrncpy(char *dst, const char *src, uint len)
\sa qstrcmp(), qstrncmp(), qstricmp(), {8-bit Character Comparisons}
*/
/*!
\relates QByteArray
Returns the CRC-32 checksum of the first \a len bytes of \a data.
*/
quint32 qChecksum(const char *data, uint len)
{
#ifndef QT_NO_COMPRESS
return libdeflate_crc32(0, data, len);
#else
Q_ASSERT_X(false, "qChecksum", "internal error");
return 0;
#endif
}
/*!
\relates QByteArray
@ -286,10 +269,7 @@ QByteArray qRandomUuid()
return QByteArray(uuidbuf, sizeof(uuidbuf));
}
#ifndef QT_NO_COMPRESS
/*!
\fn QByteArray qCompress(const QByteArray& data, int compressionLevel)
\relates QByteArray
Compresses the \a data byte array and returns the compressed data
@ -423,7 +403,6 @@ QByteArray qUncompress(const char* data, int nbytes)
}
return result;
}
#endif // QT_NO_COMPRESS
QByteArray::Data QByteArray::shared_null = { QAtomicInt(1),
0, 0, shared_null.array, {0} };

View file

@ -43,7 +43,7 @@ inline uint qstrnlen(const char *str, uint maxlen)
{ return str ? uint(strnlen(str, maxlen)) : 0; }
Q_CORE_EXPORT char* qstrcpy(char *dst, const char *src);
Q_CORE_EXPORT char* qstrncpy(char *dst, const char *src, uint len);
Q_CORE_EXPORT char* qstrncpy(char *dst, const char *src, const uint len);
inline int qstrcmp(const char *str1, const char *str2)
{
@ -51,7 +51,7 @@ inline int qstrcmp(const char *str1, const char *str2)
: (str1 ? 1 : (str2 ? -1 : 0));
}
inline int qstrncmp(const char *str1, const char *str2, uint len)
inline int qstrncmp(const char *str1, const char *str2, const uint len)
{
return (str1 && str2) ? strncmp(str1, str2, len)
: (str1 ? 1 : (str2 ? -1 : 0));
@ -62,14 +62,12 @@ inline int qstricmp(const char *str1, const char *str2)
: (str1 ? 1 : (str2 ? -1 : 0));
}
inline int qstrnicmp(const char *str1, const char *str2, uint len)
inline int qstrnicmp(const char *str1, const char *str2, const uint len)
{
return (str1 && str2) ? strncasecmp(str1, str2, len)
: (str1 ? 1 : (str2 ? -1 : 0));
}
Q_CORE_EXPORT quint32 qChecksum(const char *s, uint len);
Q_CORE_EXPORT QByteArray qRandomUuid();
class QByteRef;
@ -481,14 +479,12 @@ Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QByteArray &);
Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QByteArray &);
#endif
#ifndef QT_NO_COMPRESS
Q_CORE_EXPORT QByteArray qCompress(const char* data, int nbytes, int compressionLevel = 1);
Q_CORE_EXPORT QByteArray qUncompress(const char* data, int nbytes);
inline QByteArray qCompress(const QByteArray& data, int compressionLevel = 1)
{ return qCompress(data.constData(), data.size(), compressionLevel); }
inline QByteArray qUncompress(const QByteArray& data)
{ return qUncompress(data.constData(), data.size()); }
#endif
Q_DECLARE_TYPEINFO(QByteArray, Q_MOVABLE_TYPE);

View file

@ -23,63 +23,19 @@
#include "qbitarray.h"
#include "qstring.h"
#include <libdeflate.h>
#include <stdlib.h>
QT_BEGIN_NAMESPACE
// ### Qt 5: see tests/benchmarks/corelib/tools/qhash/qhash_string.cpp
// Hashing of the whole string is a waste of cycles.
/*
These functions are based on Peter J. Weinberger's hash function
(from the Dragon Book). The constant 24 in the original function
was replaced with 23 to produce fewer collisions on input such as
"a", "aa", "aaa", "aaaa", ...
*/
static inline uint hash(const uchar *p, int n)
uint qHash(const char *key, const uint len)
{
uint h = 0;
while (n--) {
h = (h << 4) + *p++;
h ^= (h & 0xf0000000) >> 23;
h &= 0x0fffffff;
}
return h;
}
static inline uint hash(const QChar *p, int n)
{
uint h = 0;
while (n--) {
h = (h << 4) + (*p++).unicode();
h ^= (h & 0xf0000000) >> 23;
h &= 0x0fffffff;
}
return h;
}
uint qHash(const QByteArray &key)
{
return hash(reinterpret_cast<const uchar *>(key.constData()), key.size());
}
uint qHash(const QString &key)
{
return hash(key.unicode(), key.size());
}
uint qHash(const QStringRef &key)
{
return hash(key.unicode(), key.size());
return libdeflate_crc32(23, key, len);
}
uint qHash(const QBitArray &bitArray)
{
return hash(reinterpret_cast<const uchar *>(bitArray.d.constData()), bitArray.d.size());
return qHash(bitArray.d.constData(), bitArray.d.size());
}
/*

View file

@ -34,6 +34,9 @@ class QByteArray;
class QString;
class QStringRef;
Q_CORE_EXPORT uint qHash(const char *key, const uint len);
Q_CORE_EXPORT uint qHash(const QBitArray &key);
inline uint qHash(const char key) { return uint(key); }
inline uint qHash(const uchar key) { return uint(key); }
inline uint qHash(const signed char key) { return uint(key); }
@ -60,11 +63,15 @@ inline uint qHash(const quint64 key)
}
inline uint qHash(const qint64 key) { return qHash(quint64(key)); }
inline uint qHash(const QChar key) { return qHash(key.unicode()); }
Q_CORE_EXPORT uint qHash(const QByteArray &key);
Q_CORE_EXPORT uint qHash(const QString &key);
Q_CORE_EXPORT uint qHash(const QStringRef &key);
Q_CORE_EXPORT uint qHash(const QBitArray &key);
inline uint qHash(const QByteArray &key) { return qHash(key.constData(), key.size()); }
inline uint qHash(const QString &key)
{
return qHash(reinterpret_cast<const char *>(key.unicode()), key.size() * sizeof(QChar));
}
inline uint qHash(const QStringRef &key)
{
return qHash(reinterpret_cast<const char *>(key.unicode()), key.size() * sizeof(QChar));
}
template <class T> inline uint qHash(const T *key)
{
return qHash(reinterpret_cast<quintptr>(key));

View file

@ -11,6 +11,7 @@ include_directories(
${CMAKE_BINARY_DIR}/include/QtCore
${CMAKE_CURRENT_SOURCE_DIR}
${ICU_INCLUDES}
${DEFLATE_INCLUDES}
)
set(MOC_SOURCES
@ -34,7 +35,6 @@ set(BOOTSTRAP_DEFINITIONS
-DQT_NO_THREAD
-DQT_NO_PROCESS
-DQT_NO_USING_NAMESPACE
-DQT_NO_COMPRESS
-DQT_NO_EXCEPTIONS
-DQT_NO_REGEXP
-DQT_NO_TEXTCODEC
@ -81,7 +81,7 @@ set(BOOTSTRAP_SOURCES
add_executable(bootstrap_moc ${BOOTSTRAP_SOURCES} ${MOC_SOURCES})
target_compile_definitions(bootstrap_moc PRIVATE ${BOOTSTRAP_DEFINITIONS})
target_link_libraries(bootstrap_moc ${ICU_LIBRARIES})
target_link_libraries(bootstrap_moc ${ICU_LIBRARIES} ${DEFLATE_LIBRARIES})
add_executable(moc ${MOC_SOURCES})
target_link_libraries(moc ${EXTRA_MOC_LIBS})

View file

@ -38,7 +38,6 @@ private slots:
void to_from_hex();
void bench_qstrcmp();
void bench_qstrncmp();
void bench_qchecksum();
};
@ -134,17 +133,6 @@ void tst_qbytearray::bench_qstrncmp()
}
}
void tst_qbytearray::bench_qchecksum()
{
static const int loremsize = lorem.size();
static const char* const loremdata = lorem.constData();
QBENCHMARK {
const int result = qChecksum(loremdata, loremsize);
Q_UNUSED(result);
}
}
QTEST_MAIN(tst_qbytearray)
#include "moc_main.cpp"

View file

@ -64,9 +64,6 @@ private slots:
void qhash_simple();
void qhash_simple_reserve();
void qhash_vs_qchecksum_data();
void qhash_vs_qchecksum();
private:
QString data();
};
@ -131,31 +128,6 @@ void tst_QHash::qhash_simple_reserve()
}
}
void tst_QHash::qhash_vs_qchecksum_data()
{
QTest::addColumn<bool>("qhash");
QTest::newRow("qHash") << true;
QTest::newRow("qChecksum") << false;
}
void tst_QHash::qhash_vs_qchecksum()
{
QFETCH(bool, qhash);
const QByteArray asciidata = data().toAscii();
if (qhash) {
QBENCHMARK {
(void)qHash(asciidata);
}
} else {
QBENCHMARK {
(void)qChecksum(asciidata.constData(), asciidata.size());
}
}
}
QTEST_MAIN(tst_QHash)
#include "moc_qhash_string.cpp"