summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@suse.cz>2012-04-21 18:58:31 +0200
committerMiklos Vajna <vmiklos@suse.cz>2012-04-21 19:16:38 +0200
commit22eb78b6eee38e11aec32909b6983becb309ce13 (patch)
tree7e50b720f77bb8039a3fa0437ee6fd7fa51d3347
parentda07d3a7bdb75efb34448dfb5ebca8b8b6135546 (diff)
fdo#44736 speed up RTF import a bit by sorting keywords
If we sort the keywords once in the constructor, then we can do binary search when looking up RTF keywords, and that speeds up the import by about 20% using the first testcase from the bug.
-rw-r--r--writerfilter/source/rtftok/rtfcontrolwords.cxx18
-rw-r--r--writerfilter/source/rtftok/rtfcontrolwords.hxx4
-rw-r--r--writerfilter/source/rtftok/rtftokenizer.cxx28
-rw-r--r--writerfilter/source/rtftok/rtftokenizer.hxx2
4 files changed, 38 insertions, 14 deletions
diff --git a/writerfilter/source/rtftok/rtfcontrolwords.cxx b/writerfilter/source/rtftok/rtfcontrolwords.cxx
index cce0c2e630db..11c4d3d7f6f0 100644
--- a/writerfilter/source/rtftok/rtfcontrolwords.cxx
+++ b/writerfilter/source/rtftok/rtfcontrolwords.cxx
@@ -27,6 +27,7 @@
#include <rtfcontrolwords.hxx>
#include <sal/macros.h>
+#include <string.h>
namespace writerfilter {
namespace rtftok {
@@ -1856,6 +1857,23 @@ RTFSymbol aRTFControlWords[] = {
};
int nRTFControlWords = SAL_N_ELEMENTS(aRTFControlWords);
+bool RTFSymbol::operator<(const RTFSymbol& rOther) const
+{
+ return strcmp(sKeyword, rOther.sKeyword) < 0;
+}
+
+RTFSymbol::RTFSymbol(const char* pKeyword)
+ : sKeyword(pKeyword)
+{
+}
+
+RTFSymbol::RTFSymbol(const char *pKeyword, int pControlType, RTFKeyword pIndex)
+ : sKeyword(pKeyword),
+ nControlType(pControlType),
+ nIndex(pIndex)
+{
+}
+
} // namespace rtftok
} // namespace writerfilter
diff --git a/writerfilter/source/rtftok/rtfcontrolwords.hxx b/writerfilter/source/rtftok/rtfcontrolwords.hxx
index 5afb8c6c3992..477ddb5fb062 100644
--- a/writerfilter/source/rtftok/rtfcontrolwords.hxx
+++ b/writerfilter/source/rtftok/rtfcontrolwords.hxx
@@ -1866,6 +1866,10 @@ struct RTFSymbol
const char *sKeyword;
int nControlType;
RTFKeyword nIndex;
+
+ bool operator<(const RTFSymbol& rOther) const;
+ RTFSymbol(const char* pKeyword);
+ RTFSymbol(const char *pKeyword, int pControlType, RTFKeyword pIndex);
};
extern RTFSymbol aRTFControlWords[];
diff --git a/writerfilter/source/rtftok/rtftokenizer.cxx b/writerfilter/source/rtftok/rtftokenizer.cxx
index f247317789ad..b40a91261664 100644
--- a/writerfilter/source/rtftok/rtftokenizer.cxx
+++ b/writerfilter/source/rtftok/rtftokenizer.cxx
@@ -45,8 +45,10 @@ namespace rtftok {
RTFTokenizer::RTFTokenizer(RTFDocumentImpl& rImport, SvStream* pInStream, uno::Reference<task::XStatusIndicator> const& xStatusIndicator)
: m_rImport(rImport),
m_pInStream(pInStream),
- m_xStatusIndicator(xStatusIndicator)
+ m_xStatusIndicator(xStatusIndicator),
+ m_aRTFControlWords(std::vector<RTFSymbol>(aRTFControlWords, aRTFControlWords + nRTFControlWords))
{
+ std::sort(m_aRTFControlWords.begin(), m_aRTFControlWords.end());
}
RTFTokenizer::~RTFTokenizer()
@@ -266,13 +268,10 @@ int RTFTokenizer::dispatchKeyword(OString& rKeyword, bool bParam, int nParam)
return 0;
/*SAL_INFO("writefilter", OSL_THIS_FUNC << ": keyword '\\" << rKeyword.getStr() <<
"' with param? " << (bParam ? 1 : 0) <<" param val: '" << (bParam ? nParam : 0) << "'");*/
- int i, ret;
- for (i = 0; i < nRTFControlWords; i++)
- {
- if (!strcmp(rKeyword.getStr(), aRTFControlWords[i].sKeyword))
- break;
- }
- if (i == nRTFControlWords)
+ RTFSymbol aSymbol(rKeyword.getStr());
+ std::vector<RTFSymbol>::iterator low = std::lower_bound(m_aRTFControlWords.begin(), m_aRTFControlWords.end(), aSymbol);
+ int i = low - m_aRTFControlWords.begin();
+ if (low == m_aRTFControlWords.end() || aSymbol < *low)
{
SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unknown keyword '\\" << rKeyword.getStr() << "'");
RTFSkipDestination aSkip(m_rImport);
@@ -280,35 +279,36 @@ int RTFTokenizer::dispatchKeyword(OString& rKeyword, bool bParam, int nParam)
return 0;
}
- switch (aRTFControlWords[i].nControlType)
+ int ret;
+ switch (m_aRTFControlWords[i].nControlType)
{
case CONTROL_FLAG:
// flags ignore any parameter by definition
- ret = m_rImport.dispatchFlag(aRTFControlWords[i].nIndex);
+ ret = m_rImport.dispatchFlag(m_aRTFControlWords[i].nIndex);
if (ret)
return ret;
break;
case CONTROL_DESTINATION:
// same for destinations
- ret = m_rImport.dispatchDestination(aRTFControlWords[i].nIndex);
+ ret = m_rImport.dispatchDestination(m_aRTFControlWords[i].nIndex);
if (ret)
return ret;
break;
case CONTROL_SYMBOL:
// and symbols
- ret = m_rImport.dispatchSymbol(aRTFControlWords[i].nIndex);
+ ret = m_rImport.dispatchSymbol(m_aRTFControlWords[i].nIndex);
if (ret)
return ret;
break;
case CONTROL_TOGGLE:
- ret = m_rImport.dispatchToggle(aRTFControlWords[i].nIndex, bParam, nParam);
+ ret = m_rImport.dispatchToggle(m_aRTFControlWords[i].nIndex, bParam, nParam);
if (ret)
return ret;
break;
case CONTROL_VALUE:
// values require a parameter by definition
if (bParam) {
- ret = m_rImport.dispatchValue(aRTFControlWords[i].nIndex, nParam);
+ ret = m_rImport.dispatchValue(m_aRTFControlWords[i].nIndex, nParam);
if (ret)
return ret;
}
diff --git a/writerfilter/source/rtftok/rtftokenizer.hxx b/writerfilter/source/rtftok/rtftokenizer.hxx
index 3b8dee03cb6a..bcaafdad8eb9 100644
--- a/writerfilter/source/rtftok/rtftokenizer.hxx
+++ b/writerfilter/source/rtftok/rtftokenizer.hxx
@@ -51,6 +51,8 @@ namespace writerfilter {
RTFDocumentImpl& m_rImport;
SvStream* m_pInStream;
uno::Reference<task::XStatusIndicator> const& m_xStatusIndicator;
+ // This is the same as m_aRTFControlWords, but sorted
+ std::vector<RTFSymbol> m_aRTFControlWords;
};
} // namespace rtftok
} // namespace writerfilter