Commit 658a6080 authored by hjk's avatar hjk Committed by Eike Ziller
Browse files

core: prevent allocations when looking up an existing Core::Id



Change-Id: I7bd2f83ffc6a57135aab9f76ff929eca48d16885
Reviewed-by: default avatarEike Ziller <eike.ziller@nokia.com>
parent fe8cead2
......@@ -49,20 +49,66 @@ namespace Core {
*/
class StringHolder
{
public:
explicit StringHolder(const char *s)
: str(s)
{
n = strlen(s);
int m = n;
h = 0;
while (m--) {
h = (h << 4) + *s++;
h ^= (h & 0xf0000000) >> 23;
h &= 0x0fffffff;
}
}
int n;
const char *str;
uint h;
};
static bool operator==(const StringHolder &sh1, const StringHolder &sh2)
{
// sh.n is unlikely to discriminate better than the hash.
return sh1.h == sh2.h && strcmp(sh1.str, sh1.str) == 0;
}
static uint qHash(const StringHolder &sh)
{
return sh.h;
}
struct IdCache : public QHash<StringHolder, int>
{
#ifndef QTC_ALLOW_STATIC_LEAKS
~IdCache()
{
for (IdCache::iterator it = begin(); it != end(); ++it)
free(const_cast<char *>(it.key().str));
}
#endif
};
static int lastUid = 0;
static QVector<QByteArray> stringFromId;
static QHash<QByteArray, int> idFromString;
static IdCache idFromString;
static int theId(const QByteArray &ba)
static int theId(const char *str)
{
QTC_CHECK(!ba.isEmpty());
int res = idFromString.value(ba);
QTC_ASSERT(str && *str, return 0);
StringHolder sh(str);
int res = idFromString.value(sh, 0);
if (res == 0) {
if (lastUid == 0)
stringFromId.append(QByteArray());
res = ++lastUid;
idFromString[ba] = res;
stringFromId.append(ba);
sh.str = strdup(sh.str);
idFromString[sh] = res;
stringFromId.append(QByteArray::fromRawData(sh.str, sh.n));
}
return res;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment