diff options
author | Kohei Yoshida <kohei.yoshida@suse.com> | 2011-09-02 14:45:27 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@suse.com> | 2011-09-02 15:52:35 -0400 |
commit | 69b6d6cfd29c2cfee92eef3faba03a78c671aac3 (patch) | |
tree | cc22913a61541b5b0dd5d664c0bfc8c3538f8ab0 | |
parent | 07d1d39fccbfef1638b7f3aaaed063f0d6f4ffa7 (diff) |
Speed up range name lookup by index.
This should speed up formula calculations considerably during xls
import since shared formulas are also stored in ScRangeName and
they are looked up by index. (bnc#715104)
-rw-r--r-- | sc/inc/rangenam.hxx | 9 | ||||
-rw-r--r-- | sc/source/core/tool/rangenam.cxx | 45 |
2 files changed, 41 insertions, 13 deletions
diff --git a/sc/inc/rangenam.hxx b/sc/inc/rangenam.hxx index 7b5036216851..a82b97887ebd 100644 --- a/sc/inc/rangenam.hxx +++ b/sc/inc/rangenam.hxx @@ -36,6 +36,7 @@ #include "scdllapi.h" #include <map> +#include <vector> #include <boost/ptr_container/ptr_set.hpp> #include <boost/ptr_container/ptr_map.hpp> @@ -181,8 +182,10 @@ bool operator< (const ScRangeData& left, const ScRangeData& right); class ScRangeName { private: + typedef std::vector<ScRangeData*> IndexDataType; typedef ::boost::ptr_set<ScRangeData> DataType; DataType maData; + IndexDataType maIndexToData; public: /// Map that manages stored ScRangeName instances. @@ -230,6 +233,12 @@ public: SC_DLLPUBLIC bool insert(ScRangeData* p); void erase(const ScRangeData& r); + + /** + * Erase by iterator position. Note that this method doesn't check for + * iterator's validity. The caller must make sure that the iterator is + * valid. + */ void erase(const iterator& itr); void clear(); bool operator== (const ScRangeName& r) const; diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx index 23e1b2f88aba..98188faa9683 100644 --- a/sc/source/core/tool/rangenam.cxx +++ b/sc/source/core/tool/rangenam.cxx @@ -782,7 +782,7 @@ void ScRangeName::copyLocalNames(const TabNameMap& rNames, TabNameCopyMap& rCopy ScRangeName::ScRangeName() {} ScRangeName::ScRangeName(const ScRangeName& r) : - maData(r.maData) {} + maData(r.maData), maIndexToData(r.maIndexToData) {} const ScRangeData* ScRangeName::findByRange(const ScRange& rRange) const { @@ -821,9 +821,12 @@ const ScRangeData* ScRangeName::findByUpperName(const OUString& rName) const ScRangeData* ScRangeName::findByIndex(sal_uInt16 i) { - DataType::iterator itr = std::find_if( - maData.begin(), maData.end(), MatchByIndex(i)); - return itr == maData.end() ? NULL : &(*itr); + if (!i) + // index should never be zero. + return NULL; + + size_t nPos = i - 1; + return nPos < maIndexToData.size() ? maIndexToData[nPos] : NULL; } void ScRangeName::UpdateReference( @@ -899,35 +902,51 @@ bool ScRangeName::insert(ScRangeData* p) if (!p->GetIndex()) { - // Assign a new index. An index must be unique. - sal_uInt16 nHigh = 0; - DataType::const_iterator itr = maData.begin(), itrEnd = maData.end(); - for (; itr != itrEnd; ++itr) + // Assign a new index. An index must be unique and is never 0. + IndexDataType::iterator itr = std::find( + maIndexToData.begin(), maIndexToData.end(), static_cast<ScRangeData*>(NULL)); + if (itr != maIndexToData.end()) { - sal_uInt16 n = itr->GetIndex(); - if (n > nHigh) - nHigh = n; + // Empty slot exists. Re-use it. + size_t nPos = std::distance(maIndexToData.begin(), itr); + p->SetIndex(nPos + 1); } - p->SetIndex(nHigh + 1); + else + // No empty slot. Append it to the end. + p->SetIndex(maIndexToData.size() + 1); } pair<DataType::iterator, bool> r = maData.insert(p); + if (r.second) + { + // Data inserted. Store its index for mapping. + size_t nPos = p->GetIndex() - 1; + if (nPos >= maIndexToData.size()) + maIndexToData.resize(nPos+1, NULL); + maIndexToData[nPos] = p; + } return r.second; } void ScRangeName::erase(const ScRangeData& r) { - maData.erase(r); + DataType::iterator itr = maData.find(r); + if (itr != maData.end()) + erase(itr); } void ScRangeName::erase(const iterator& itr) { + sal_uInt16 nIndex = itr->GetIndex(); maData.erase(itr); + if (nIndex < maIndexToData.size()) + maIndexToData[nIndex] = NULL; } void ScRangeName::clear() { maData.clear(); + maIndexToData.clear(); } bool ScRangeName::operator== (const ScRangeName& r) const |