eliminate m_filevaluemap by using source tagging

instead of having a second value map per included file, simply tag all
values with the project file they are coming from. a lot cleaner and
marginally faster.
This commit is contained in:
Oswald Buddenhagen
2011-04-20 18:19:33 +02:00
parent 85801227a9
commit 5e23cf2968
3 changed files with 28 additions and 24 deletions

View File

@@ -279,7 +279,6 @@ public:
FunctionDefs m_functionDefs; FunctionDefs m_functionDefs;
ProStringList m_returnValue; ProStringList m_returnValue;
QStack<QHash<ProString, ProStringList> > m_valuemapStack; // VariableName must be us-ascii, the content however can be non-us-ascii. QStack<QHash<ProString, ProStringList> > m_valuemapStack; // VariableName must be us-ascii, the content however can be non-us-ascii.
QHash<const ProFile*, QHash<ProString, ProStringList> > m_filevaluemap; // Variables per include file
QString m_tmp1, m_tmp2, m_tmp3, m_tmp[2]; // Temporaries for efficient toQString QString m_tmp1, m_tmp2, m_tmp3, m_tmp[2]; // Temporaries for efficient toQString
ProFileOption *m_option; ProFileOption *m_option;
@@ -514,6 +513,7 @@ ProString ProFileEvaluator::Private::getStr(const ushort *&tokPtr)
{ {
uint len = *tokPtr++; uint len = *tokPtr++;
ProString ret(m_current.pro->items(), tokPtr - m_current.pro->tokPtr(), len, NoHash); ProString ret(m_current.pro->items(), tokPtr - m_current.pro->tokPtr(), len, NoHash);
ret.setSource(m_current.pro);
tokPtr += len; tokPtr += len;
return ret; return ret;
} }
@@ -1107,7 +1107,6 @@ void ProFileEvaluator::Private::visitProVariable(
// We could make a union of modified and unmodified values, // We could make a union of modified and unmodified values,
// but this will break just as much as it fixes, so leave it as is. // but this will break just as much as it fixes, so leave it as is.
replaceInList(&valuesRef(varName), regexp, replace, global, m_tmp2); replaceInList(&valuesRef(varName), regexp, replace, global, m_tmp2);
replaceInList(&m_filevaluemap[currentProFile()][varName], regexp, replace, global, m_tmp2);
} }
} else { } else {
ProStringList varVal = expandVariableReferences(tokPtr, sizeHint); ProStringList varVal = expandVariableReferences(tokPtr, sizeHint);
@@ -1118,7 +1117,6 @@ void ProFileEvaluator::Private::visitProVariable(
if (!m_skipLevel) { if (!m_skipLevel) {
zipEmpty(&varVal); zipEmpty(&varVal);
m_valuemapStack.top()[varName] = varVal; m_valuemapStack.top()[varName] = varVal;
m_filevaluemap[currentProFile()][varName] = varVal;
} }
} else { } else {
zipEmpty(&varVal); zipEmpty(&varVal);
@@ -1139,31 +1137,23 @@ void ProFileEvaluator::Private::visitProVariable(
if (!has.contains(s)) if (!has.contains(s))
v << s; v << s;
} }
// These values will not be used for further processing inside
// the evaluator. Duplicate elimination happens later.
m_filevaluemap[currentProFile()][varName] += varVal;
} }
} }
break; break;
case TokAppendUnique: // *= case TokAppendUnique: // *=
if (!m_skipLevel || m_cumulative) { if (!m_skipLevel || m_cumulative)
insertUnique(&valuesRef(varName), varVal); insertUnique(&valuesRef(varName), varVal);
insertUnique(&m_filevaluemap[currentProFile()][varName], varVal);
}
break; break;
case TokAppend: // += case TokAppend: // +=
if (!m_skipLevel || m_cumulative) { if (!m_skipLevel || m_cumulative) {
zipEmpty(&varVal); zipEmpty(&varVal);
valuesRef(varName) += varVal; valuesRef(varName) += varVal;
m_filevaluemap[currentProFile()][varName] += varVal;
} }
break; break;
case TokRemove: // -= case TokRemove: // -=
if (!m_cumulative) { if (!m_cumulative) {
if (!m_skipLevel) { if (!m_skipLevel)
removeEach(&valuesRef(varName), varVal); removeEach(&valuesRef(varName), varVal);
removeEach(&m_filevaluemap[currentProFile()][varName], varVal);
}
} else { } else {
// We are stingy with our values, too. // We are stingy with our values, too.
} }
@@ -3277,7 +3267,13 @@ QStringList ProFileEvaluator::values(const QString &variableName) const
QStringList ProFileEvaluator::values(const QString &variableName, const ProFile *pro) const QStringList ProFileEvaluator::values(const QString &variableName, const ProFile *pro) const
{ {
// It makes no sense to put any kind of magic into expanding these // It makes no sense to put any kind of magic into expanding these
return expandEnvVars(d->m_filevaluemap.value(pro).value(ProString(variableName))); const ProStringList &values = d->m_valuemapStack.at(0).value(ProString(variableName));
QStringList ret;
ret.reserve(values.size());
foreach (const ProString &str, values)
if (str.sourceFile() == pro)
ret << expandEnvVars(str.toQString());
return ret;
} }
QStringList ProFileEvaluator::absolutePathValues( QStringList ProFileEvaluator::absolutePathValues(

View File

@@ -53,55 +53,55 @@ uint ProString::hash(const QChar *p, int n)
} }
ProString::ProString() : ProString::ProString() :
m_offset(0), m_length(0), m_hash(0x80000000) m_offset(0), m_length(0), m_file(0), m_hash(0x80000000)
{ {
} }
ProString::ProString(const ProString &other) : ProString::ProString(const ProString &other) :
m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_hash(other.m_hash) m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(other.m_hash)
{ {
} }
ProString::ProString(const ProString &other, OmitPreHashing) : ProString::ProString(const ProString &other, OmitPreHashing) :
m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_hash(0x80000000) m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(0x80000000)
{ {
} }
ProString::ProString(const QString &str) : ProString::ProString(const QString &str) :
m_string(str), m_offset(0), m_length(str.length()) m_string(str), m_offset(0), m_length(str.length()), m_file(0)
{ {
updatedHash(); updatedHash();
} }
ProString::ProString(const QString &str, OmitPreHashing) : ProString::ProString(const QString &str, OmitPreHashing) :
m_string(str), m_offset(0), m_length(str.length()), m_hash(0x80000000) m_string(str), m_offset(0), m_length(str.length()), m_file(0), m_hash(0x80000000)
{ {
} }
ProString::ProString(const char *str) : ProString::ProString(const char *str) :
m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)) m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0)
{ {
updatedHash(); updatedHash();
} }
ProString::ProString(const char *str, OmitPreHashing) : ProString::ProString(const char *str, OmitPreHashing) :
m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_hash(0x80000000) m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0), m_hash(0x80000000)
{ {
} }
ProString::ProString(const QString &str, int offset, int length) : ProString::ProString(const QString &str, int offset, int length) :
m_string(str), m_offset(offset), m_length(length) m_string(str), m_offset(offset), m_length(length), m_file(0)
{ {
updatedHash(); updatedHash();
} }
ProString::ProString(const QString &str, int offset, int length, uint hash) : ProString::ProString(const QString &str, int offset, int length, uint hash) :
m_string(str), m_offset(offset), m_length(length), m_hash(hash) m_string(str), m_offset(offset), m_length(length), m_file(0), m_hash(hash)
{ {
} }
ProString::ProString(const QString &str, int offset, int length, ProStringConstants::OmitPreHashing) : ProString::ProString(const QString &str, int offset, int length, ProStringConstants::OmitPreHashing) :
m_string(str), m_offset(offset), m_length(length), m_hash(0x80000000) m_string(str), m_offset(offset), m_length(length), m_file(0), m_hash(0x80000000)
{ {
} }
@@ -198,6 +198,8 @@ ProString &ProString::append(const ProString &other, bool *pending)
ptr = prepareAppend(other.m_length); ptr = prepareAppend(other.m_length);
} }
memcpy(ptr, other.m_string.constData() + other.m_offset, other.m_length * 2); memcpy(ptr, other.m_string.constData() + other.m_offset, other.m_length * 2);
if (other.m_file)
m_file = other.m_file;
} }
if (pending) if (pending)
*pending = true; *pending = true;
@@ -236,6 +238,8 @@ ProString &ProString::append(const ProStringList &other, bool *pending, bool ski
memcpy(ptr, str.m_string.constData() + str.m_offset, str.m_length * 2); memcpy(ptr, str.m_string.constData() + str.m_offset, str.m_length * 2);
ptr += str.m_length; ptr += str.m_length;
} }
if (other.last().m_file)
m_file = other.last().m_file;
} }
if (pending) if (pending)
*pending = true; *pending = true;

View File

@@ -57,6 +57,7 @@ enum OmitPreHashing { NoHash };
} }
class ProStringList; class ProStringList;
class ProFile;
class ProString { class ProString {
public: public:
@@ -70,6 +71,8 @@ public:
ProString(const QString &str, int offset, int length); ProString(const QString &str, int offset, int length);
ProString(const QString &str, int offset, int length, uint hash); ProString(const QString &str, int offset, int length, uint hash);
ProString(const QString &str, int offset, int length, ProStringConstants::OmitPreHashing); ProString(const QString &str, int offset, int length, ProStringConstants::OmitPreHashing);
void setSource(const ProFile *pro) { m_file = pro; }
const ProFile *sourceFile() const { return m_file; }
QString toQString() const; QString toQString() const;
QString &toQString(QString &tmp) const; QString &toQString(QString &tmp) const;
ProString &operator+=(const ProString &other); ProString &operator+=(const ProString &other);
@@ -95,6 +98,7 @@ public:
private: private:
QString m_string; QString m_string;
int m_offset, m_length; int m_offset, m_length;
const ProFile *m_file;
mutable uint m_hash; mutable uint m_hash;
QChar *prepareAppend(int extraLen); QChar *prepareAppend(int extraLen);
uint updatedHash() const; uint updatedHash() const;