make QProcessEnvironment on Unix cache converted variable names

the converted keys also cache their hash, as they are used only for the
purpose of looking up in a qhash.

Reviewed-by: thiago
Reviewed-by: dt
(cherry picked from commit 18f1613aa8ece72d24ac10e28f06e3db1d8ce400)
This commit is contained in:
Oswald Buddenhagen 2011-04-28 10:53:14 +02:00 committed by Olivier Goffart
parent 299d10549f
commit 9ff8d1c34a
3 changed files with 50 additions and 11 deletions

View File

@ -202,12 +202,19 @@ QStringList QProcessEnvironmentPrivate::keys() const
return result;
}
void QProcessEnvironmentPrivate::insert(const Hash &h)
void QProcessEnvironmentPrivate::insert(const QProcessEnvironmentPrivate &other)
{
Hash::ConstIterator it = h.constBegin(),
end = h.constEnd();
Hash::ConstIterator it = other.hash.constBegin(),
end = other.hash.constEnd();
for ( ; it != end; ++it)
hash.insert(it.key(), it.value());
#ifdef Q_OS_UNIX
QHash<QString, Key>::ConstIterator nit = other.nameMap.constBegin(),
nend = other.nameMap.constEnd();
for ( ; nit != nend; ++nit)
nameMap.insert(nit.key(), nit.value());
#endif
}
/*!
@ -288,6 +295,8 @@ void QProcessEnvironment::clear()
{
if (d)
d->hash.clear();
// Unix: Don't clear d->nameMap, as the environment is likely to be
// re-populated with the same keys again.
}
/*!
@ -409,7 +418,7 @@ void QProcessEnvironment::insert(const QProcessEnvironment &e)
return;
// d detaches from null
d->insert(e.d->hash);
d->insert(*e.d);
}
void QProcessPrivate::Channel::clear()

View File

@ -101,11 +101,33 @@ public:
inline Value prepareValue(const QString &value) const { return value; }
inline QString valueToString(const Value &value) const { return value; }
#else
typedef QByteArray Key;
class Key
{
public:
Key() : hash(0) {}
explicit Key(const QByteArray &other) : key(other), hash(qHash(key)) {}
Key(const Key &other) { *this = other; }
bool operator==(const Key &other) const { return key == other.key; }
QByteArray key;
uint hash;
};
typedef QByteArray Value;
inline Key prepareName(const QString &name) const { return name.toLocal8Bit(); }
inline QString nameToString(const Key &name) const { return QString::fromLocal8Bit(name); }
inline Key prepareName(const QString &name) const
{
Key &ent = nameMap[name];
if (ent.key.isEmpty())
ent = Key(name.toLocal8Bit());
return ent;
}
inline QString nameToString(const Key &name) const
{
const QString sname = QString::fromLocal8Bit(name.key);
nameMap[sname] = name;
return sname;
}
inline Value prepareValue(const QString &value) const { return value.toLocal8Bit(); }
inline QString valueToString(const Value &value) const { return QString::fromLocal8Bit(value); }
#endif
@ -113,14 +135,22 @@ public:
typedef QHash<Key, Value> Hash;
Hash hash;
#ifdef Q_OS_UNIX
typedef QHash<QString, Key> NameHash;
mutable NameHash nameMap;
#endif
static QProcessEnvironment fromList(const QStringList &list);
QStringList toList() const;
QStringList keys() const;
void insert(const Hash &hash);
void insert(const QProcessEnvironmentPrivate &other);
};
#ifdef Q_OS_WIN
Q_DECLARE_TYPEINFO(QProcessEnvironmentPrivate::Key, Q_MOVABLE_TYPE);
#ifdef Q_OS_WIN
inline uint qHash(const QProcessEnvironmentPrivate::Key &key) { return qHash(key.toCaseFolded()); }
#else
inline uint qHash(const QProcessEnvironmentPrivate::Key &key) { return key.hash; }
#endif
class QProcessPrivate : public QIODevicePrivate

View File

@ -483,7 +483,7 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm
#endif
const QByteArray envLibraryPath = qgetenv(libraryPath);
bool needToAddLibraryPath = !envLibraryPath.isEmpty() &&
!environment.contains(libraryPath);
!environment.contains(QProcessEnvironmentPrivate::Key(QByteArray(libraryPath)));
char **envp = new char *[environment.count() + 2];
envp[environment.count()] = 0;
@ -492,7 +492,7 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm
QProcessEnvironmentPrivate::Hash::ConstIterator it = environment.constBegin();
const QProcessEnvironmentPrivate::Hash::ConstIterator end = environment.constEnd();
for ( ; it != end; ++it) {
QByteArray key = it.key();
QByteArray key = it.key().key;
QByteArray value = it.value();
key.reserve(key.length() + 1 + value.length());
key.append('=');