[Libreoffice-commits] core.git: Branch 'private/kohei/xlsx-import-speedup' - 5 commits - formula/source sc/inc sc/source svl/source
Kohei Yoshida
kohei.yoshida at collabora.com
Thu Nov 7 00:53:00 CET 2013
formula/source/core/api/FormulaCompiler.cxx | 66 +++--
sc/inc/compiler.hxx | 3
sc/inc/document.hxx | 1
sc/source/core/data/documen2.cxx | 5
sc/source/core/data/poolhelp.cxx | 28 +-
sc/source/core/inc/poolhelp.hxx | 4
sc/source/core/tool/compiler.cxx | 62 ++---
sc/source/filter/inc/formulabuffer.hxx | 38 ++-
sc/source/filter/oox/formulabuffer.cxx | 318 ++++++++++++++++++----------
svl/source/numbers/zforfind.cxx | 6
svl/source/numbers/zforfind.hxx | 3
11 files changed, 354 insertions(+), 180 deletions(-)
New commits:
commit 4af2f3c8cc98949271df5dc70358e3d33e751719
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Nov 6 18:51:34 2013 -0500
Perform formula cell compilations in multiple threads during xlsx import.
One sheet per thread. Right now the thread count is set to 1 due to non
re-entrancy of a large portion of Calc core, and beyond. We need to fix
that first before setting the thread count to more than 1.
Change-Id: I6997c1e9540de939f1f00b1798e2b32059787ae5
diff --git a/sc/source/filter/inc/formulabuffer.hxx b/sc/source/filter/inc/formulabuffer.hxx
index f9e5229..7e881ee 100644
--- a/sc/source/filter/inc/formulabuffer.hxx
+++ b/sc/source/filter/inc/formulabuffer.hxx
@@ -13,6 +13,8 @@
#include <utility>
#include "oox/helper/refmap.hxx"
#include "oox/helper/refvector.hxx"
+#include "salhelper/thread.hxx"
+#include "osl/mutex.hxx"
#include "workbookhelper.hxx"
#include <com/sun/star/table/CellAddress.hpp>
#include <com/sun/star/table/CellRangeAddress.hpp>
@@ -29,6 +31,21 @@ namespace oox { namespace xls {
class FormulaBuffer : public WorkbookHelper
{
+ class FinalizeThread : public salhelper::Thread
+ {
+ FormulaBuffer& mrParent;
+ size_t mnThreadCount;
+ public:
+ FinalizeThread( FormulaBuffer& rParent, size_t nThreadCount );
+ virtual ~FinalizeThread();
+
+ protected:
+ virtual void execute();
+ };
+
+ friend class FinalizeThread;
+
+public:
/**
* Represents a shared formula definition.
*/
@@ -74,6 +91,20 @@ class FormulaBuffer : public WorkbookHelper
TokenRangeAddressItem( const TokenAddressItem& rTokenAndAddress, const ::com::sun::star::table::CellRangeAddress& rCellRangeAddress ) : maTokenAndAddress( rTokenAndAddress ), maCellRangeAddress( rCellRangeAddress ) {}
};
+ typedef std::pair<com::sun::star::table::CellAddress, double> ValueAddressPair;
+
+ struct SheetItem
+ {
+ std::vector<TokenAddressItem>* mpCellFormulas;
+ std::vector<TokenRangeAddressItem>* mpArrayFormulas;
+ std::vector<ValueAddressPair>* mpCellFormulaValues;
+ std::vector<SharedFormulaEntry>* mpSharedFormulaEntries;
+ std::vector<SharedFormulaDesc>* mpSharedFormulaIDs;
+
+ SheetItem();
+ };
+
+private:
typedef ::std::map< SCTAB, std::vector<TokenAddressItem> > FormulaDataMap;
typedef ::std::map< SCTAB, std::vector<TokenRangeAddressItem> > ArrayFormulaDataMap;
// sheet -> list of shared formula descriptions
@@ -81,19 +112,16 @@ class FormulaBuffer : public WorkbookHelper
// sheet -> stuff needed to create shared formulae
typedef ::std::map< SCTAB, std::vector<SharedFormulaEntry> > SheetToFormulaEntryMap;
- typedef ::std::pair< ::com::sun::star::table::CellAddress, double > ValueAddressPair;
typedef ::std::map< SCTAB, std::vector<ValueAddressPair> > FormulaValueMap;
+ osl::Mutex maMtxData;
FormulaDataMap maCellFormulas;
ArrayFormulaDataMap maCellArrayFormulas;
SheetToFormulaEntryMap maSharedFormulas;
SheetToSharedFormulaid maSharedFormulaIds;
FormulaValueMap maCellFormulaValues;
- void applyArrayFormulas( const std::vector< TokenRangeAddressItem >& rVector );
- void applyCellFormulas( const std::vector< TokenAddressItem >& rVector );
- void applyCellFormulaValues( const std::vector< ValueAddressPair >& rVector );
- void applySharedFormulas( SCTAB nTab );
+ SheetItem getSheetItem( SCTAB nTab );
public:
explicit FormulaBuffer( const WorkbookHelper& rHelper );
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index 04be139..c3e1d24 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -33,114 +33,22 @@ using namespace ::com::sun::star::table;
using namespace ::com::sun::star::sheet;
using namespace ::com::sun::star::container;
-namespace oox { namespace xls {
-
-FormulaBuffer::SharedFormulaEntry::SharedFormulaEntry(
- const table::CellAddress& rAddr, const table::CellRangeAddress& rRange,
- const OUString& rTokenStr, sal_Int32 nSharedId ) :
- maAddress(rAddr), maRange(rRange), maTokenStr(rTokenStr), mnSharedId(nSharedId) {}
-
-FormulaBuffer::SharedFormulaDesc::SharedFormulaDesc(
- const com::sun::star::table::CellAddress& rAddr, sal_Int32 nSharedId,
- const OUString& rCellValue, sal_Int32 nValueType ) :
- maAddress(rAddr), mnSharedId(nSharedId), maCellValue(rCellValue), mnValueType(nValueType) {}
-
-FormulaBuffer::FormulaBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper )
-{
-}
-
-void FormulaBuffer::finalizeImport()
-{
- ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
-
- ScDocument& rDoc = getScDocument();
- rDoc.SetAutoNameCache( new ScAutoNameCache( &rDoc ) );
- for (SCTAB nTab = 0, nElem = rDoc.GetTableCount(); nTab < nElem; ++nTab)
- {
- double fPosition = static_cast< double> (nTab + 1) /static_cast<double>(nElem);
- xFormulaBar->setPosition( fPosition );
+#include <boost/scoped_ptr.hpp>
- applySharedFormulas(nTab);
-
- FormulaDataMap::iterator cellIt = maCellFormulas.find( nTab );
- if ( cellIt != maCellFormulas.end() )
- {
- applyCellFormulas( cellIt->second );
- }
-
- ArrayFormulaDataMap::iterator itArray = maCellArrayFormulas.find( nTab );
- if ( itArray != maCellArrayFormulas.end() )
- {
- applyArrayFormulas( itArray->second );
- }
-
- FormulaValueMap::iterator itValues = maCellFormulaValues.find( nTab );
- if ( itValues != maCellFormulaValues.end() )
- {
- std::vector< ValueAddressPair > & rVector = itValues->second;
- applyCellFormulaValues( rVector );
- }
- }
- rDoc.SetAutoNameCache( NULL );
- xFormulaBar->setPosition( 1.0 );
-}
-
-void FormulaBuffer::applyCellFormulas( const std::vector< TokenAddressItem >& rVector )
-{
- ScDocumentImport& rDoc = getDocImport();
- ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
- for ( std::vector< TokenAddressItem >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
- {
- ScAddress aPos;
- ScUnoConversion::FillScAddress(aPos, it->maCellAddress);
- ScCompiler aCompiler(&rDoc.getDoc(), aPos);
- aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
- ScTokenArray* pCode = aCompiler.CompileString(it->maTokenStr);
- if (!pCode)
- continue;
+namespace oox { namespace xls {
- rDoc.setFormulaCell(aPos, pCode);
- }
-}
+namespace {
-void FormulaBuffer::applyCellFormulaValues( const std::vector< ValueAddressPair >& rVector )
+void applySharedFormulas(
+ ScDocumentImport& rDoc,
+ SvNumberFormatter& rFormatter,
+ std::vector<FormulaBuffer::SharedFormulaEntry>& rSharedFormulas,
+ std::vector<FormulaBuffer::SharedFormulaDesc>& rCells )
{
- ScDocument& rDoc = getScDocument();
- for ( std::vector< ValueAddressPair >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
- {
- ScAddress aCellPos;
- ScUnoConversion::FillScAddress( aCellPos, it->first );
- ScFormulaCell* pCell = rDoc.GetFormulaCell(aCellPos);
- if (pCell)
- {
- pCell->SetHybridDouble( it->second );
- pCell->ResetDirty();
- pCell->SetChanged(false);
- }
- }
-}
-
-void FormulaBuffer::applySharedFormulas( SCTAB nTab )
-{
- SheetToFormulaEntryMap::const_iterator itShared = maSharedFormulas.find(nTab);
- if (itShared == maSharedFormulas.end())
- // There is no shared formulas for this sheet.
- return;
-
- SheetToSharedFormulaid::const_iterator itCells = maSharedFormulaIds.find(nTab);
- if (itCells == maSharedFormulaIds.end())
- // There is no formula cells that use shared formulas for this sheet.
- return;
-
- const std::vector<SharedFormulaEntry>& rSharedFormulas = itShared->second;
- const std::vector<SharedFormulaDesc>& rCells = itCells->second;
-
- ScDocumentImport& rDoc = getDocImport();
-
sc::SharedFormulaGroups aGroups;
{
// Process shared formulas first.
- std::vector<SharedFormulaEntry>::const_iterator it = rSharedFormulas.begin(), itEnd = rSharedFormulas.end();
+ std::vector<FormulaBuffer::SharedFormulaEntry>::const_iterator it = rSharedFormulas.begin(), itEnd = rSharedFormulas.end();
for (; it != itEnd; ++it)
{
const table::CellAddress& rAddr = it->maAddress;
@@ -150,6 +58,7 @@ void FormulaBuffer::applySharedFormulas( SCTAB nTab )
ScAddress aPos;
ScUnoConversion::FillScAddress(aPos, rAddr);
ScCompiler aComp(&rDoc.getDoc(), aPos);
+ aComp.SetNumberFormatter(&rFormatter);
aComp.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
ScTokenArray* pArray = aComp.CompileString(rTokenStr);
if (pArray)
@@ -159,7 +68,7 @@ void FormulaBuffer::applySharedFormulas( SCTAB nTab )
{
// Process formulas that use shared formulas.
- std::vector<SharedFormulaDesc>::const_iterator it = rCells.begin(), itEnd = rCells.end();
+ std::vector<FormulaBuffer::SharedFormulaDesc>::const_iterator it = rCells.begin(), itEnd = rCells.end();
for (; it != itEnd; ++it)
{
const table::CellAddress& rAddr = it->maAddress;
@@ -194,10 +103,32 @@ void FormulaBuffer::applySharedFormulas( SCTAB nTab )
}
}
-void FormulaBuffer::applyArrayFormulas( const std::vector< TokenRangeAddressItem >& rVector )
+void applyCellFormulas(
+ ScDocumentImport& rDoc, SvNumberFormatter& rFormatter,
+ const std::vector<FormulaBuffer::TokenAddressItem>& rCells )
{
- ScDocumentImport& rDocImport = getDocImport();
- std::vector<TokenRangeAddressItem>::const_iterator it = rVector.begin(), itEnd = rVector.end();
+ ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
+ std::vector<FormulaBuffer::TokenAddressItem>::const_iterator it = rCells.begin(), itEnd = rCells.end();
+ for (; it != itEnd; ++it)
+ {
+ ScAddress aPos;
+ ScUnoConversion::FillScAddress(aPos, it->maCellAddress);
+ ScCompiler aCompiler(&rDoc.getDoc(), aPos);
+ aCompiler.SetNumberFormatter(&rFormatter);
+ aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
+ ScTokenArray* pCode = aCompiler.CompileString(it->maTokenStr);
+ if (!pCode)
+ continue;
+
+ rDoc.setFormulaCell(aPos, pCode);
+ }
+}
+
+void applyArrayFormulas(
+ ScDocumentImport& rDoc, SvNumberFormatter& rFormatter,
+ const std::vector<FormulaBuffer::TokenRangeAddressItem>& rArrays )
+{
+ std::vector<FormulaBuffer::TokenRangeAddressItem>::const_iterator it = rArrays.begin(), itEnd = rArrays.end();
for (; it != itEnd; ++it)
{
ScAddress aPos;
@@ -205,12 +136,185 @@ void FormulaBuffer::applyArrayFormulas( const std::vector< TokenRangeAddressItem
ScRange aRange;
ScUnoConversion::FillScRange(aRange, it->maCellRangeAddress);
- ScCompiler aComp(&rDocImport.getDoc(), aPos);
+ ScCompiler aComp(&rDoc.getDoc(), aPos);
+ aComp.SetNumberFormatter(&rFormatter);
aComp.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
boost::scoped_ptr<ScTokenArray> pArray(aComp.CompileString(it->maTokenAndAddress.maTokenStr));
if (pArray)
- rDocImport.setMatrixCells(aRange, *pArray, formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
+ rDoc.setMatrixCells(aRange, *pArray, formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
+ }
+}
+
+void applyCellFormulaValues(
+ ScDocumentImport& rDoc, const std::vector<FormulaBuffer::ValueAddressPair>& rVector )
+{
+ std::vector<FormulaBuffer::ValueAddressPair>::const_iterator it = rVector.begin(), itEnd = rVector.end();
+ for (; it != itEnd; ++it)
+ {
+ ScAddress aCellPos;
+ ScUnoConversion::FillScAddress(aCellPos, it->first);
+ ScFormulaCell* pCell = rDoc.getDoc().GetFormulaCell(aCellPos);
+ if (pCell)
+ {
+ pCell->SetHybridDouble(it->second);
+ pCell->ResetDirty();
+ pCell->SetChanged(false);
+ }
+ }
+}
+
+class WorkerThread : public salhelper::Thread
+{
+ ScDocumentImport& mrDoc;
+ FormulaBuffer::SheetItem& mrItem;
+ boost::scoped_ptr<SvNumberFormatter> mpFormatter;
+
+ WorkerThread( const WorkerThread& );
+ WorkerThread& operator= ( const WorkerThread& );
+
+public:
+ WorkerThread( ScDocumentImport& rDoc, FormulaBuffer::SheetItem& rItem, SvNumberFormatter* pFormatter ) :
+ salhelper::Thread("xlsx-import-formula-buffer-worker-thread"),
+ mrDoc(rDoc), mrItem(rItem), mpFormatter(pFormatter) {}
+
+ virtual ~WorkerThread() {}
+
+protected:
+ virtual void execute()
+ {
+ if (mrItem.mpSharedFormulaEntries && mrItem.mpSharedFormulaIDs)
+ applySharedFormulas(mrDoc, *mpFormatter, *mrItem.mpSharedFormulaEntries, *mrItem.mpSharedFormulaIDs);
+
+ if (mrItem.mpCellFormulas)
+ applyCellFormulas(mrDoc, *mpFormatter, *mrItem.mpCellFormulas);
+
+ if (mrItem.mpArrayFormulas)
+ applyArrayFormulas(mrDoc, *mpFormatter, *mrItem.mpArrayFormulas);
+
+ if (mrItem.mpCellFormulaValues)
+ applyCellFormulaValues(mrDoc, *mrItem.mpCellFormulaValues);
+ }
+};
+
+}
+
+FormulaBuffer::SharedFormulaEntry::SharedFormulaEntry(
+ const table::CellAddress& rAddr, const table::CellRangeAddress& rRange,
+ const OUString& rTokenStr, sal_Int32 nSharedId ) :
+ maAddress(rAddr), maRange(rRange), maTokenStr(rTokenStr), mnSharedId(nSharedId) {}
+
+FormulaBuffer::SharedFormulaDesc::SharedFormulaDesc(
+ const com::sun::star::table::CellAddress& rAddr, sal_Int32 nSharedId,
+ const OUString& rCellValue, sal_Int32 nValueType ) :
+ maAddress(rAddr), mnSharedId(nSharedId), maCellValue(rCellValue), mnValueType(nValueType) {}
+
+FormulaBuffer::SheetItem::SheetItem() :
+ mpCellFormulas(NULL),
+ mpArrayFormulas(NULL),
+ mpCellFormulaValues(NULL),
+ mpSharedFormulaEntries(NULL),
+ mpSharedFormulaIDs(NULL) {}
+
+FormulaBuffer::FinalizeThread::FinalizeThread( FormulaBuffer& rParent, size_t nThreadCount ) :
+ salhelper::Thread("xlsx-import-formula-buffer-finalize-thread"),
+ mrParent(rParent), mnThreadCount(nThreadCount) {}
+
+FormulaBuffer::FinalizeThread::~FinalizeThread() {}
+
+void FormulaBuffer::FinalizeThread::execute()
+{
+ ScDocumentImport& rDoc = mrParent.getDocImport();
+ rDoc.getDoc().SetAutoNameCache(new ScAutoNameCache(&rDoc.getDoc()));
+ SCTAB nTabCount = rDoc.getDoc().GetTableCount();
+
+ std::vector<SheetItem> aSheetItems;
+ aSheetItems.reserve(nTabCount);
+ for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
+ aSheetItems.push_back(mrParent.getSheetItem(nTab));
+
+ typedef rtl::Reference<WorkerThread> WorkerThreadRef;
+ std::vector<WorkerThreadRef> aThreads;
+ aThreads.reserve(mnThreadCount);
+
+ std::vector<SheetItem>::iterator it = aSheetItems.begin(), itEnd = aSheetItems.end();
+
+ while (it != itEnd)
+ {
+ for (size_t i = 0; i < mnThreadCount; ++i)
+ {
+ if (it == itEnd)
+ break;
+
+ WorkerThreadRef xThread(new WorkerThread(rDoc, *it, rDoc.getDoc().CreateFormatTable()));
+ ++it;
+ aThreads.push_back(xThread);
+ xThread->launch();
+ }
+
+ for (size_t i = 0, n = aThreads.size(); i < n; ++i)
+ {
+ if (aThreads[i].is())
+ aThreads[i]->join();
+ }
+
+ aThreads.clear();
+ }
+
+ rDoc.getDoc().SetAutoNameCache(NULL);
+}
+
+FormulaBuffer::FormulaBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper )
+{
+}
+
+void FormulaBuffer::finalizeImport()
+{
+ ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
+
+ rtl::Reference<FinalizeThread> xThreadMgr(new FinalizeThread(*this, 1));
+ xThreadMgr->launch();
+
+ if (xThreadMgr.is())
+ xThreadMgr->join();
+
+ xFormulaBar->setPosition( 1.0 );
+}
+
+FormulaBuffer::SheetItem FormulaBuffer::getSheetItem( SCTAB nTab )
+{
+ osl::MutexGuard aGuard(&maMtxData);
+
+ SheetItem aItem;
+ {
+ FormulaDataMap::iterator it = maCellFormulas.find(nTab);
+ if (it != maCellFormulas.end())
+ aItem.mpCellFormulas = &it->second;
+ }
+
+ {
+ ArrayFormulaDataMap::iterator it = maCellArrayFormulas.find(nTab);
+ if (it != maCellArrayFormulas.end())
+ aItem.mpArrayFormulas = &it->second;
+ }
+
+ {
+ FormulaValueMap::iterator it = maCellFormulaValues.find(nTab);
+ if (it != maCellFormulaValues.end())
+ aItem.mpCellFormulaValues = &it->second;
+ }
+
+ {
+ SheetToFormulaEntryMap::iterator it = maSharedFormulas.find(nTab);
+ if (it != maSharedFormulas.end())
+ aItem.mpSharedFormulaEntries = &it->second;
+ }
+
+ {
+ SheetToSharedFormulaid::iterator it = maSharedFormulaIds.find(nTab);
+ if (it != maSharedFormulaIds.end())
+ aItem.mpSharedFormulaIDs = &it->second;
}
+ return aItem;
}
void FormulaBuffer::createSharedFormulaMapEntry(
commit 9e8523defe69d99517957ee808b77256bdf32fb9
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Nov 6 18:43:47 2013 -0500
Allow instantiation of more than one SvNumberFormatter from the document.
Change-Id: Ide6875e031268337bf6a21286176a38905c12691
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 6929e9b..09f1466 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1621,6 +1621,7 @@ public:
const ScMarkData* pMarkData = NULL );
SC_DLLPUBLIC SvNumberFormatter* GetFormatTable() const;
+ SC_DLLPUBLIC SvNumberFormatter* CreateFormatTable() const;
void Sort( SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress );
SCSIZE Query( SCTAB nTab, const ScQueryParam& rQueryParam, bool bKeepSub );
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 1e0bb87..23a4bcf 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -491,6 +491,11 @@ SvNumberFormatter* ScDocument::GetFormatTable() const
return xPoolHelper->GetFormTable();
}
+SvNumberFormatter* ScDocument::CreateFormatTable() const
+{
+ return xPoolHelper->CreateNumberFormatter();
+}
+
SfxItemPool* ScDocument::GetEditPool() const
{
return xPoolHelper->GetEditPool();
diff --git a/sc/source/core/data/poolhelp.cxx b/sc/source/core/data/poolhelp.cxx
index b6f027a..74d5cbe 100644
--- a/sc/source/core/data/poolhelp.cxx
+++ b/sc/source/core/data/poolhelp.cxx
@@ -71,14 +71,8 @@ SfxItemPool* ScPoolHelper::GetEnginePool() const
}
SvNumberFormatter* ScPoolHelper::GetFormTable() const
{
- if ( !pFormTable )
- {
- pFormTable = new SvNumberFormatter( comphelper::getProcessComponentContext(), ScGlobal::eLnge );
- pFormTable->SetColorLink( LINK( m_pSourceDoc, ScDocument, GetUserDefinedColor ) );
- pFormTable->SetEvalDateFormat( NF_EVALDATEFORMAT_INTL_FORMAT );
-
- UseDocOptions(); // null date, year2000, std precision
- }
+ if (!pFormTable)
+ pFormTable = CreateNumberFormatter();
return pFormTable;
}
@@ -100,6 +94,24 @@ void ScPoolHelper::SetFormTableOpt(const ScDocOptions& rOpt)
UseDocOptions(); // #i105512# if the number formatter exists, update its settings
}
+SvNumberFormatter* ScPoolHelper::CreateNumberFormatter() const
+{
+ SvNumberFormatter* p = NULL;
+ {
+ osl::MutexGuard aGuard(&maMtxCreateNumFormatter);
+ p = new SvNumberFormatter(comphelper::getProcessComponentContext(), ScGlobal::eLnge);
+ }
+ p->SetColorLink( LINK(m_pSourceDoc, ScDocument, GetUserDefinedColor) );
+ p->SetEvalDateFormat(NF_EVALDATEFORMAT_INTL_FORMAT);
+
+ sal_uInt16 d,m,y;
+ aOpt.GetDate(d, m, y);
+ p->ChangeNullDate(d, m, y);
+ p->ChangeStandardPrec(aOpt.GetStdPrecision());
+ p->SetYear2000(aOpt.GetYear2000());
+ return p;
+}
+
void ScPoolHelper::SourceDocumentGone()
{
// reset all pointers to the source document
diff --git a/sc/source/core/inc/poolhelp.hxx b/sc/source/core/inc/poolhelp.hxx
index 6eaa0a9..c60bd1b 100644
--- a/sc/source/core/inc/poolhelp.hxx
+++ b/sc/source/core/inc/poolhelp.hxx
@@ -23,6 +23,7 @@
#include <rtl/ref.hxx>
#include <salhelper/simplereferenceobject.hxx>
#include "docoptio.hxx"
+#include "osl/mutex.hxx"
class ScDocument;
class ScDocumentPool;
@@ -34,6 +35,7 @@ class SfxItemPool;
class ScPoolHelper : public salhelper::SimpleReferenceObject
{
private:
+ mutable osl::Mutex maMtxCreateNumFormatter;
ScDocOptions aOpt;
ScDocumentPool* pDocPool;
rtl::Reference< ScStyleSheetPool > mxStylePool;
@@ -59,6 +61,8 @@ public:
SfxItemPool* GetEnginePool() const;
void SetFormTableOpt(const ScDocOptions& rOpt);
+
+ SvNumberFormatter* CreateNumberFormatter() const;
};
#endif
commit 39074224e5f233c85c677b4f3bb9797e4e94a477
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Nov 6 18:41:18 2013 -0500
Allow non-pooled instance of SvNumberFormatter inside ScCompiler.
Change-Id: I645079254621c2f2684a69116b094e37e46f46f4
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index c16f749..0cd47c5 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -312,6 +312,8 @@ private:
ScDocument* pDoc;
ScAddress aPos;
+ SvNumberFormatter* mpFormatter;
+
// For CONV_XL_OOX, may be set via API by MOOXML filter.
::com::sun::star::uno::Sequence< const ::com::sun::star::sheet::ExternalLinkInfo > maExternalLinks;
@@ -400,6 +402,7 @@ public:
void SetGrammar( const formula::FormulaGrammar::Grammar eGrammar );
+ void SetNumberFormatter( SvNumberFormatter* pFormatter );
EncodeUrlMode GetEncodeUrlMode() const;
private:
/** Set grammar and reference convention from within SetFormulaLanguage()
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 95e4ef0..41e1d56 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -239,6 +239,11 @@ void ScCompiler::SetGrammar( const FormulaGrammar::Grammar eGrammar )
}
}
+void ScCompiler::SetNumberFormatter( SvNumberFormatter* pFormatter )
+{
+ mpFormatter = pFormatter;
+}
+
ScCompiler::EncodeUrlMode ScCompiler::GetEncodeUrlMode() const
{
return meEncodeUrlMode;
@@ -1640,6 +1645,7 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos,ScTokenArra
: FormulaCompiler(rArr),
pDoc( pDocument ),
aPos( rPos ),
+ mpFormatter(pDoc->GetFormatTable()),
pCharClass( ScGlobal::pCharClass ),
mnPredetectedReference(0),
mnRangeOpPosInSymbol(-1),
@@ -1656,6 +1662,7 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos)
:
pDoc( pDocument ),
aPos( rPos ),
+ mpFormatter(pDoc->GetFormatTable()),
pCharClass( ScGlobal::pCharClass ),
mnPredetectedReference(0),
mnRangeOpPosInSymbol(-1),
@@ -2517,40 +2524,37 @@ bool ScCompiler::IsOpCode2( const OUString& rName )
bool ScCompiler::IsValue( const OUString& rSym )
{
double fVal;
- sal_uInt32 nIndex = ( mxSymbols->isEnglish() ?
- pDoc->GetFormatTable()->GetStandardIndex( LANGUAGE_ENGLISH_US ) : 0 );
+ sal_uInt32 nIndex = mxSymbols->isEnglish() ? mpFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US) : 0;
- if (pDoc->GetFormatTable()->IsNumberFormat( rSym, nIndex, fVal ) )
- {
- sal_uInt16 nType = pDoc->GetFormatTable()->GetType(nIndex);
+ if (!mpFormatter->IsNumberFormat(rSym, nIndex, fVal))
+ return false;
- // Don't accept 3:3 as time, it is a reference to entire row 3 instead.
- // Dates should never be entered directly and automatically converted
- // to serial, because the serial would be wrong if null-date changed.
- // Usually it wouldn't be accepted anyway because the date separator
- // clashed with other separators or operators.
- if (nType & (NUMBERFORMAT_TIME | NUMBERFORMAT_DATE))
- return false;
+ sal_uInt16 nType = mpFormatter->GetType(nIndex);
- if (nType == NUMBERFORMAT_LOGICAL)
- {
- const sal_Unicode* p = aFormula.getStr() + nSrcPos;
- while( *p == ' ' )
- p++;
- if (*p == '(')
- return false; // Boolean function instead.
- }
+ // Don't accept 3:3 as time, it is a reference to entire row 3 instead.
+ // Dates should never be entered directly and automatically converted
+ // to serial, because the serial would be wrong if null-date changed.
+ // Usually it wouldn't be accepted anyway because the date separator
+ // clashed with other separators or operators.
+ if (nType & (NUMBERFORMAT_TIME | NUMBERFORMAT_DATE))
+ return false;
- if( nType == NUMBERFORMAT_TEXT )
- // HACK: number too big!
- SetError( errIllegalArgument );
- ScRawToken aToken;
- aToken.SetDouble( fVal );
- pRawToken = aToken.Clone();
- return true;
+ if (nType == NUMBERFORMAT_LOGICAL)
+ {
+ const sal_Unicode* p = aFormula.getStr() + nSrcPos;
+ while( *p == ' ' )
+ p++;
+ if (*p == '(')
+ return false; // Boolean function instead.
}
- else
- return false;
+
+ if( nType == NUMBERFORMAT_TEXT )
+ // HACK: number too big!
+ SetError( errIllegalArgument );
+ ScRawToken aToken;
+ aToken.SetDouble( fVal );
+ pRawToken = aToken.Clone();
+ return true;
}
bool ScCompiler::IsString()
commit 091b0ad48d3cf94108e8ffb73894629ae0a6c9ee
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Nov 6 18:34:18 2013 -0500
Protect those global symbols containers with mutex during initialization.
Change-Id: Id15b3e1a2bfebd2ea795fd412a259f125f5d9bab
diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index fda54bd..804fb03 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -24,6 +24,8 @@
#include "core_resource.hxx"
#include "core_resource.hrc"
+#include "osl/mutex.hxx"
+
#include <svl/zforlist.hxx>
#include <tools/rc.hxx>
#include <tools/rcid.h>
@@ -39,8 +41,7 @@ namespace formula
static const sal_Char* pInternal[ 1 ] = { "TTT" };
-namespace
-{
+namespace {
class FormulaCompilerRecursionGuard
{
@@ -248,6 +249,13 @@ const sal_Unicode* lcl_UnicodeStrChr( const sal_Unicode* pStr, sal_Unicode c )
return NULL;
}
+struct OpCodeMapData
+{
+ FormulaCompiler::NonConstOpCodeMapPtr mxSymbolMap;
+ osl::Mutex maMtx;
+};
+
+
} // namespace
@@ -625,21 +633,25 @@ FormulaCompiler::OpCodeMapPtr FormulaCompiler::CreateOpCodeMap(
void lcl_fillNativeSymbols( FormulaCompiler::NonConstOpCodeMapPtr& xMap, bool bDestroy = false )
{
- static FormulaCompiler::NonConstOpCodeMapPtr s_SymbolMap;
+ static OpCodeMapData aSymbolMap;
+ osl::MutexGuard aGuard(&aSymbolMap.maMtx);
+
if ( bDestroy )
{
- s_SymbolMap.reset();
+ aSymbolMap.mxSymbolMap.reset();
}
- else if ( !s_SymbolMap.get() )
+ else if (!aSymbolMap.mxSymbolMap)
{
// Core
- s_SymbolMap.reset( new FormulaCompiler::OpCodeMap( SC_OPCODE_LAST_OPCODE_ID + 1, true,
- FormulaGrammar::GRAM_NATIVE_UI));
+ aSymbolMap.mxSymbolMap.reset(
+ new FormulaCompiler::OpCodeMap(
+ SC_OPCODE_LAST_OPCODE_ID + 1, true, FormulaGrammar::GRAM_NATIVE_UI));
OModuleClient aModuleClient;
- OpCodeList aOpCodeListNative( RID_STRLIST_FUNCTION_NAMES, s_SymbolMap );
+ OpCodeList aOpCodeListNative(RID_STRLIST_FUNCTION_NAMES, aSymbolMap.mxSymbolMap);
// No AddInMap for native core mapping.
}
- xMap = s_SymbolMap;
+
+ xMap = aSymbolMap.mxSymbolMap;
}
const OUString& FormulaCompiler::GetNativeSymbol( OpCode eOp )
@@ -661,34 +673,38 @@ void FormulaCompiler::InitSymbolsNative() const
void FormulaCompiler::InitSymbolsEnglish() const
{
- static NonConstOpCodeMapPtr s_sSymbol;
- if ( !s_sSymbol.get() )
- loadSymbols( RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_ENGLISH, s_sSymbol);
- mxSymbolsEnglish = s_sSymbol;
+ static OpCodeMapData aMap;
+ osl::MutexGuard aGuard(&aMap.maMtx);
+ if (!aMap.mxSymbolMap)
+ loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_ENGLISH, aMap.mxSymbolMap);
+ mxSymbolsEnglish = aMap.mxSymbolMap;
}
void FormulaCompiler::InitSymbolsPODF() const
{
- static NonConstOpCodeMapPtr s_sSymbol;
- if ( !s_sSymbol.get() )
- loadSymbols( RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_PODF, s_sSymbol);
- mxSymbolsPODF = s_sSymbol;
+ static OpCodeMapData aMap;
+ osl::MutexGuard aGuard(&aMap.maMtx);
+ if (!aMap.mxSymbolMap)
+ loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_PODF, aMap.mxSymbolMap);
+ mxSymbolsPODF = aMap.mxSymbolMap;
}
void FormulaCompiler::InitSymbolsODFF() const
{
- static NonConstOpCodeMapPtr s_sSymbol;
- if ( !s_sSymbol.get() )
- loadSymbols( RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF, FormulaGrammar::GRAM_ODFF, s_sSymbol);
- mxSymbolsODFF = s_sSymbol;
+ static OpCodeMapData aMap;
+ osl::MutexGuard aGuard(&aMap.maMtx);
+ if (!aMap.mxSymbolMap)
+ loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF, FormulaGrammar::GRAM_ODFF, aMap.mxSymbolMap);
+ mxSymbolsODFF = aMap.mxSymbolMap;
}
void FormulaCompiler::InitSymbolsEnglishXL() const
{
- static NonConstOpCodeMapPtr s_sSymbol;
- if ( !s_sSymbol.get() )
- loadSymbols( RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_ENGLISH, s_sSymbol);
- mxSymbolsEnglishXL = s_sSymbol;
+ static OpCodeMapData aMap;
+ osl::MutexGuard aGuard(&aMap.maMtx);
+ if (!aMap.mxSymbolMap)
+ loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_ENGLISH, aMap.mxSymbolMap);
+ mxSymbolsEnglishXL = aMap.mxSymbolMap;
// TODO: For now, just replace the separators to the Excel English
// variants. Later, if we want to properly map Excel functions with Calc
commit 42d42c72086aaed09834ed07071f6d5dd7e5e9b0
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Nov 6 14:55:41 2013 -0500
Make TransformInput() a non-member function.
Change-Id: Ieb077b6ce661e2885d6010519f137235a048f9df
diff --git a/svl/source/numbers/zforfind.cxx b/svl/source/numbers/zforfind.cxx
index 9cd3362..3726c33 100644
--- a/svl/source/numbers/zforfind.cxx
+++ b/svl/source/numbers/zforfind.cxx
@@ -147,8 +147,8 @@ inline bool ImpSvNumberInputScan::MyIsdigit( sal_Unicode c )
return c < 128 && isdigit( (unsigned char) c );
}
-
-void ImpSvNumberInputScan::TransformInput( OUString& rStr )
+// native number transliteration if necessary
+void TransformInput( SvNumberFormatter* pFormatter, OUString& rStr )
{
sal_Int32 nPos, nLen;
for ( nPos = 0, nLen = rStr.getLength(); nPos < nLen; ++nPos )
@@ -3271,7 +3271,7 @@ bool ImpSvNumberInputScan::IsNumberFormat( const OUString& rString, // s
// NoMoreUpperNeeded, all comparisons on UpperCase
aString = pFormatter->GetCharClass()->uppercase( rString );
// convert native number to ASCII if necessary
- TransformInput( aString );
+ TransformInput(pFormatter, aString);
res = IsNumberFormatMain( aString, pFormat );
}
diff --git a/svl/source/numbers/zforfind.hxx b/svl/source/numbers/zforfind.hxx
index 4c070a1..6e24040 100644
--- a/svl/source/numbers/zforfind.hxx
+++ b/svl/source/numbers/zforfind.hxx
@@ -362,9 +362,6 @@ private:
static inline bool MyIsdigit( sal_Unicode c );
- // native number transliteration if necessary
- void TransformInput( OUString& rString );
-
/** Whether input matches locale dependent date acceptance pattern.
@param nStartPatternAt
More information about the Libreoffice-commits
mailing list