forked from qt-creator/qt-creator
core: prevent allocations when looking up an existing Core::Id
Change-Id: I7bd2f83ffc6a57135aab9f76ff929eca48d16885 Reviewed-by: Eike Ziller <eike.ziller@nokia.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user