diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-07-01 16:31:17 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-07-01 08:32:57 +0200 |
commit | 67347f700568607497b36c5d71e7eb89b35f363e (patch) | |
tree | c32f784047b4252a0d1648a3c9cdfcb976b0108b /src/declarative/qml/v8/qhashedstring_p.h | |
parent | 628a5cd0669dbfb6a4f2b60f5b59b044f8ca2bbb (diff) |
Improve performance of v8 string hashes by using symbol id
The symbol id is a unique integer associated with a string symbol in
V8. If two symbol ids are equal, then the strings are also equal.
However, if the two symbol ids are not equal, the strings may still
be equal.
Change-Id: Ic28f51a1eba568ae4b2a054e278f6e5e454725d6
Reviewed-on: http://codereview.qt.nokia.com/990
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'src/declarative/qml/v8/qhashedstring_p.h')
-rw-r--r-- | src/declarative/qml/v8/qhashedstring_p.h | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/src/declarative/qml/v8/qhashedstring_p.h b/src/declarative/qml/v8/qhashedstring_p.h index 0dd111e189..b178af7e4a 100644 --- a/src/declarative/qml/v8/qhashedstring_p.h +++ b/src/declarative/qml/v8/qhashedstring_p.h @@ -95,11 +95,12 @@ public: inline quint32 hash() const; inline int length() const; + inline quint32 symbolId() const; + inline v8::Handle<v8::String> string() const; private: - quint32 m_hash; - int m_length; + v8::String::CompleteHashData m_hash; v8::Handle<v8::String> m_string; }; @@ -137,7 +138,7 @@ class QStringHashNode { public: QStringHashNode(const QHashedString &key) - : nlist(0), next(0), key(key) { + : nlist(0), next(0), key(key), symbolId(0) { if (isAscii()) ascii = key.toAscii(); } @@ -145,6 +146,7 @@ public: QStringHashNode *next; QHashedString key; QByteArray ascii; + quint32 symbolId; inline bool equals(v8::Handle<v8::String> string) { return !ascii.isEmpty() && string->Equals((char*)ascii.constData(), ascii.length()) || @@ -188,6 +190,7 @@ private: inline Node *findNode(const QHashedStringRef &) const; inline Node *findNode(const QHashedV8String &) const; + inline Node *findSymbolNode(const QHashedV8String &) const; Node *createNode(const QHashedString &, const T &); public: @@ -393,6 +396,27 @@ typename QStringHash<T>::Node *QStringHash<T>::findNode(const QHashedV8String &s } template<class T> +typename QStringHash<T>::Node *QStringHash<T>::findSymbolNode(const QHashedV8String &string) const +{ + Q_ASSERT(string.symbolId() != 0); + + QStringHashNode *node = 0; + if (data.numBuckets) { + quint32 hash = string.hash(); + quint32 symbolId = string.symbolId(); + node = data.buckets[hash % data.numBuckets]; + int length = string.length(); + while (node && (length != node->key.length() || hash != node->key.hash() || + !(node->symbolId == symbolId || node->equals(string.string())))) + node = node->next; + if (node) + node->symbolId = symbolId; + } + + return (Node *)node; +} + +template<class T> T *QStringHash<T>::value(const QString &key) const { Node *n = findNode(key); @@ -416,7 +440,7 @@ T *QStringHash<T>::value(const QHashedStringRef &key) const template<class T> T *QStringHash<T>::value(const QHashedV8String &string) const { - Node *n = findNode(string); + Node *n = string.symbolId()?findSymbolNode(string):findNode(string); return n?&n->value:0; } @@ -532,44 +556,47 @@ bool QHashedString::isUpper(const QChar &qc) } QHashedV8String::QHashedV8String() -: m_hash(0) { } QHashedV8String::QHashedV8String(v8::Handle<v8::String> string) -: m_hash(string->Hash()), m_length(string->Length()), m_string(string) +: m_hash(string->CompleteHash()), m_string(string) { Q_ASSERT(!m_string.IsEmpty()); } QHashedV8String::QHashedV8String(const QHashedV8String &string) -: m_hash(string.m_hash), m_length(string.m_length), m_string(string.m_string) +: m_hash(string.m_hash), m_string(string.m_string) { } QHashedV8String &QHashedV8String::operator=(const QHashedV8String &other) { m_hash = other.m_hash; - m_length = other.m_length; m_string = other.m_string; return *this; } bool QHashedV8String::operator==(const QHashedV8String &string) { - return m_hash == string.m_hash && m_length == string.m_length && + return m_hash.hash == string.m_hash.hash && m_hash.length == string.m_hash.length && m_string.IsEmpty() == m_string.IsEmpty() && (m_string.IsEmpty() || m_string->StrictEquals(string.m_string)); } quint32 QHashedV8String::hash() const { - return m_hash; + return m_hash.hash; } int QHashedV8String::length() const { - return m_length; + return m_hash.length; +} + +quint32 QHashedV8String::symbolId() const +{ + return m_hash.symbol_id; } v8::Handle<v8::String> QHashedV8String::string() const |