From b309f9449a03319cdf9208a89f7d37ea26e227a5 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen <oswald.buddenhagen@nokia.com> Date: Wed, 3 Feb 2010 16:50:11 +0100 Subject: [PATCH] directly link ProItems instead of using QList<ProItem*> somewhat faster again --- src/shared/proparser/profileevaluator.cpp | 76 ++++++++++++----------- src/shared/proparser/proitems.cpp | 5 +- src/shared/proparser/proitems.h | 13 +++- src/shared/proparser/prowriter.cpp | 4 +- 4 files changed, 57 insertions(+), 41 deletions(-) diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index 75a8d8ccf1e..71101e41b92 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -192,11 +192,23 @@ public: /////////////// Reading pro file + struct BlockCursor { + BlockCursor() : cursor(0) {} + BlockCursor(ProBlock *blk) : block(blk), cursor(blk->itemsRef()) {} + ~BlockCursor() { if (cursor) *cursor = 0; } + void set(ProBlock *blk) { if (cursor) *cursor = 0; block = blk; cursor = blk->itemsRef(); } + void reset() { if (cursor) { *cursor = 0; cursor = 0; } } + void append(ProItem *item) { *cursor = item; cursor = item->nextRef(); } + bool isValid() const { return cursor != 0; } + ProBlock *block; + ProItem **cursor; + }; + bool read(ProFile *pro); bool read(ProBlock *pro, const QString &content); bool readInternal(ProBlock *pro, const QString &content, ushort *buf); - ProBlock *currentBlock(); + BlockCursor ¤tBlock(); void updateItem(ushort *uc, ushort *ptr); ProVariable *startVariable(ushort *uc, ushort *ptr); void finalizeVariable(ProVariable *var, ushort *uc, ushort *ptr); @@ -205,8 +217,8 @@ public: void leaveScope(); void finalizeBlock(); - QStack<ProBlock *> m_blockstack; - ProBlock *m_block; + QStack<BlockCursor> m_blockstack; + BlockCursor m_block; /////////////// Evaluating pro file contents @@ -355,9 +367,7 @@ bool ProFileEvaluator::Private::read(ProBlock *pro, const QString &content) bool ProFileEvaluator::Private::readInternal(ProBlock *pro, const QString &in, ushort *buf) { // Parser state - m_block = 0; - m_blockstack.clear(); - m_blockstack.push(pro); + m_blockstack.push(BlockCursor(pro)); // We rely on QStrings being null-terminated, so don't maintain a global end pointer. const ushort *cur = (const ushort *)in.unicode(); @@ -387,6 +397,8 @@ bool ProFileEvaluator::Private::readInternal(ProBlock *pro, const QString &in, u ++m_lineNo; goto freshLine; } + m_block.reset(); + m_blockstack.clear(); // FIXME: should actually check the state here return true; } if (c != ' ' && c != '\t' && c != '\r') @@ -560,9 +572,9 @@ bool ProFileEvaluator::Private::readInternal(ProBlock *pro, const QString &in, u void ProFileEvaluator::Private::finalizeBlock() { - if (m_blockstack.top()->blockKind() & ProBlock::SingleLine) + if (m_blockstack.top().block->blockKind() & ProBlock::SingleLine) leaveScope(); - m_block = 0; + m_block.reset(); } ProVariable *ProFileEvaluator::Private::startVariable(ushort *uc, ushort *ptr) @@ -610,8 +622,7 @@ void ProFileEvaluator::Private::finalizeVariable(ProVariable *variable, ushort * { variable->setValue(QString((QChar*)uc, ptr - uc)); - ProBlock *block = m_blockstack.top(); - block->appendItem(variable); + m_blockstack.top().append(variable); } void ProFileEvaluator::Private::insertOperator(const char op) @@ -628,28 +639,27 @@ void ProFileEvaluator::Private::insertOperator(const char op) opkind = ProOperator::OrOperator; } - ProBlock * const block = currentBlock(); ProOperator * const proOp = new ProOperator(opkind); proOp->setLineNumber(m_lineNo); - block->appendItem(proOp); + currentBlock().append(proOp); } void ProFileEvaluator::Private::enterScope(bool multiLine) { - ProBlock *parent = currentBlock(); + BlockCursor &parent = currentBlock(); + ProBlock *block = new ProBlock(); block->setLineNumber(m_lineNo); - parent->setBlockKind(ProBlock::ScopeKind); - - parent->appendItem(block); - if (multiLine) block->setBlockKind(ProBlock::ScopeContentsKind); else block->setBlockKind(ProBlock::ScopeContentsKind|ProBlock::SingleLine); + m_blockstack.push(BlockCursor(block)); - m_blockstack.push(block); - m_block = 0; + parent.block->setBlockKind(ProBlock::ScopeKind); + parent.append(block); + + m_block.reset(); } void ProFileEvaluator::Private::leaveScope() @@ -661,16 +671,14 @@ void ProFileEvaluator::Private::leaveScope() finalizeBlock(); } -ProBlock *ProFileEvaluator::Private::currentBlock() +ProFileEvaluator::Private::BlockCursor &ProFileEvaluator::Private::currentBlock() { - if (m_block) - return m_block; - - ProBlock *parent = m_blockstack.top(); - m_block = new ProBlock(); - m_block->setLineNumber(m_lineNo); - parent->appendItem(m_block); - + if (!m_block.isValid()) { + ProBlock *blk = new ProBlock(); + blk->setLineNumber(m_lineNo); + m_blockstack.top().append(blk); + m_block.set(blk); + } return m_block; } @@ -681,7 +689,6 @@ void ProFileEvaluator::Private::updateItem(ushort *uc, ushort *ptr) QString proItem = QString((QChar*)uc, ptr - uc); - ProBlock *block = currentBlock(); ProItem *item; if (proItem.endsWith(QLatin1Char(')'))) { item = new ProFunction(proItem); @@ -689,7 +696,7 @@ void ProFileEvaluator::Private::updateItem(ushort *uc, ushort *ptr) item = new ProCondition(proItem); } item->setLineNumber(m_lineNo); - block->appendItem(item); + currentBlock().append(item); } //////// Evaluator tools ///////// @@ -866,15 +873,14 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitProBlock(ProBlock *block) } } ProItem::ProItemReturn rt = ProItem::ReturnTrue; - QList<ProItem *> items = block->items(); - for (int i = 0; i < items.count(); ++i) { - rt = visitProItem(items.at(i)); + for (ProItem *item = block->items(); item; item = item->next()) { + rt = visitProItem(item); if (rt != ProItem::ReturnTrue && rt != ProItem::ReturnFalse) { if (rt == ProItem::ReturnLoop) { rt = ProItem::ReturnTrue; while (visitProLoopIteration()) - for (int j = i; ++j < items.count(); ) { - rt = visitProItem(items.at(j)); + for (ProItem *lItem = item; (lItem = lItem->next()); ) { + rt = visitProItem(lItem); if (rt != ProItem::ReturnTrue && rt != ProItem::ReturnFalse) { if (rt == ProItem::ReturnNext) { rt = ProItem::ReturnTrue; diff --git a/src/shared/proparser/proitems.cpp b/src/shared/proparser/proitems.cpp index 236ed5070ac..e1301cbb1d6 100644 --- a/src/shared/proparser/proitems.cpp +++ b/src/shared/proparser/proitems.cpp @@ -36,17 +36,20 @@ QT_BEGIN_NAMESPACE ProBlock::ProBlock() : ProItem(BlockKind) { + m_proitems = 0; m_blockKind = 0; m_refCount = 1; } ProBlock::~ProBlock() { - foreach (ProItem *itm, m_proitems) + for (ProItem *itm, *nitm = m_proitems; (itm = nitm); ) { + nitm = itm->m_next; if (itm->kind() == BlockKind) static_cast<ProBlock *>(itm)->deref(); else delete itm; + } } ProFile::ProFile(const QString &fileName) diff --git a/src/shared/proparser/proitems.h b/src/shared/proparser/proitems.h index b55933dce2b..46d085f066f 100644 --- a/src/shared/proparser/proitems.h +++ b/src/shared/proparser/proitems.h @@ -63,9 +63,15 @@ public: int lineNumber() const { return m_lineNumber; } void setLineNumber(int lineNumber) { m_lineNumber = lineNumber; } + ProItem *next() const { return m_next; } + ProItem **nextRef() { return &m_next; } + private: + ProItem *m_next; ProItemKind m_kind; int m_lineNumber; + + friend class ProBlock; // C++ is braindead ... }; class ProBlock : public ProItem @@ -83,16 +89,17 @@ public: ProBlock(); ~ProBlock(); - void appendItem(ProItem *proitem) { m_proitems << proitem; } - QList<ProItem *> items() const { return m_proitems; } void setBlockKind(int blockKind) { m_blockKind = blockKind; } int blockKind() const { return m_blockKind; } + ProItem *items() const { return m_proitems; } + ProItem **itemsRef() { return &m_proitems; } + void ref() { ++m_refCount; } void deref() { if (!--m_refCount) delete this; } private: - QList<ProItem *> m_proitems; + ProItem *m_proitems; int m_blockKind; int m_refCount; }; diff --git a/src/shared/proparser/prowriter.cpp b/src/shared/proparser/prowriter.cpp index 3c8942600c3..9a5e797f698 100644 --- a/src/shared/proparser/prowriter.cpp +++ b/src/shared/proparser/prowriter.cpp @@ -40,7 +40,7 @@ void ProWriter::addFiles(ProFile *profile, QStringList *lines, const QStringList &vars) { // Check if variable item exists as child of root item - foreach (ProItem *item, profile->items()) { + for (ProItem *item = profile->items(); item; item = item->next()) { if (item->kind() == ProItem::VariableKind) { ProVariable *proVar = static_cast<ProVariable*>(item); if (vars.contains(proVar->variable()) @@ -87,7 +87,7 @@ void ProWriter::addFiles(ProFile *profile, QStringList *lines, static void findProVariables(ProBlock *block, const QStringList &vars, QList<ProVariable *> *proVars) { - foreach (ProItem *item, block->items()) { + for (ProItem *item = block->items(); item; item = item->next()) { if (item->kind() == ProItem::BlockKind) { findProVariables(static_cast<ProBlock*>(item), vars, proVars); } else if (item->kind() == ProItem::VariableKind) { -- GitLab