From 66ff3f7fa4cd157d9b79e2fb7fe8cce98c913e08 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sat, 27 Apr 2013 01:02:06 +0200 Subject: Add qt_hash(QStringRef) overload This enables fixing a performance regression compared to Qt 4. Also, add some qt_hash tests. Change-Id: Id830e17dec99fb67e5930c80029ac2233b2f427e Reviewed-by: Oswald Buddenhagen --- src/corelib/tools/qhash.cpp | 25 +++++++++++++++++++++---- src/corelib/tools/qhash.h | 1 + tests/auto/corelib/tools/qhash/tst_qhash.cpp | 22 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index ed756cbeb6..59e7a979dc 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -235,17 +235,16 @@ static void qt_initialize_qhash_seed() \internal Private copy of the implementation of the Qt 4 qHash algorithm for strings, + (that is, QChar-based arrays, so all QString-like classes), to be used wherever the result is somehow stored or reused across multiple Qt versions. The public qHash implementation can change at any time, therefore one must not rely on the fact that it will always give the same results. - This function must *never* change its results. + The qt_hash functions must *never* change their results. */ -uint qt_hash(const QString &key) Q_DECL_NOTHROW +static uint qt_hash(const QChar *p, int n) Q_DECL_NOTHROW { - const QChar *p = key.unicode(); - int n = key.size(); uint h = 0; while (n--) { @@ -256,6 +255,24 @@ uint qt_hash(const QString &key) Q_DECL_NOTHROW return h; } +/*! + \internal + \overload +*/ +uint qt_hash(const QString &key) Q_DECL_NOTHROW +{ + return qt_hash(key.unicode(), key.size()); +} + +/*! + \internal + \overload +*/ +uint qt_hash(const QStringRef &key) Q_DECL_NOTHROW +{ + return qt_hash(key.unicode(), key.size()); +} + /* The prime_deltas array is a table of selected prime values, even though it doesn't look like one. The primes we are using are 1, diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 5d9238f453..e99a67d1e3 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -92,6 +92,7 @@ Q_CORE_EXPORT uint qHash(const QStringRef &key, uint seed = 0) Q_DECL_NOTHROW; Q_CORE_EXPORT uint qHash(const QBitArray &key, uint seed = 0) Q_DECL_NOTHROW; Q_CORE_EXPORT uint qHash(QLatin1String key, uint seed = 0) Q_DECL_NOTHROW; Q_CORE_EXPORT uint qt_hash(const QString &key) Q_DECL_NOTHROW; +Q_CORE_EXPORT uint qt_hash(const QStringRef &key) Q_DECL_NOTHROW; #if defined(Q_CC_MSVC) #pragma warning( push ) diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 1cbf181286..71428310b8 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -75,6 +75,9 @@ private slots: void const_shared_null(); void twoArguments_qHash(); void initializerList(); + + void qthash_data(); + void qthash(); }; struct Foo { @@ -1330,5 +1333,24 @@ void tst_QHash::initializerList() #endif } +void tst_QHash::qthash_data() +{ + QTest::addColumn("key"); + QTest::addColumn("hash"); + + QTest::newRow("null") << QString() << 0u; + QTest::newRow("empty") << QStringLiteral("") << 0u; + QTest::newRow("abcdef") << QStringLiteral("abcdef") << 108567222u; + QTest::newRow("tqbfjotld") << QStringLiteral("The quick brown fox jumps over the lazy dog") << 140865879u; + QTest::newRow("42") << QStringLiteral("42") << 882u; +} + +void tst_QHash::qthash() +{ + QFETCH(QString, key); + const uint result = qt_hash(key); + QTEST(result, "hash"); +} + QTEST_APPLESS_MAIN(tst_QHash) #include "tst_qhash.moc" -- cgit v1.2.3