diff options
author | Miklos Vajna <vmiklos@suse.cz> | 2012-04-21 18:58:31 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@suse.cz> | 2012-04-21 19:16:38 +0200 |
commit | 22eb78b6eee38e11aec32909b6983becb309ce13 (patch) | |
tree | 7e50b720f77bb8039a3fa0437ee6fd7fa51d3347 | |
parent | da07d3a7bdb75efb34448dfb5ebca8b8b6135546 (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.cxx | 18 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfcontrolwords.hxx | 4 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtftokenizer.cxx | 28 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtftokenizer.hxx | 2 |
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 |