summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>2011-04-28 10:53:14 +0200
committerOlivier Goffart <olivier.goffart@nokia.com>2011-05-10 12:54:52 +0200
commit9ff8d1c34a74bd852a7eb2016b46ab2904340b05 (patch)
tree923330e5d529a8b616c4d4ecbf6c42d48f14a5b9
parent299d10549f5aff50cd6211eb3d3e58c17f13be81 (diff)
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)
-rw-r--r--src/corelib/io/qprocess.cpp17
-rw-r--r--src/corelib/io/qprocess_p.h40
-rw-r--r--src/corelib/io/qprocess_unix.cpp4
3 files changed, 50 insertions, 11 deletions
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index ffd5ff0ff8..80e0b0f36f 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -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()
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index 14fc9f32ce..9a9981efda 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -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
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 7ee66ec955..7edefd3820 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -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('=');