Kaydet (Commit) 60cc84c9 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Move the compare-matrix code to ScMatrix, for much faster execution.

Change-Id: I3c4f255469b48cfd6f132503ff695e347d8ae912
üst 4162c889
...@@ -35,7 +35,10 @@ struct Compare ...@@ -35,7 +35,10 @@ struct Compare
bool bVal[2]; bool bVal[2];
bool bEmpty[2]; bool bEmpty[2];
Compare( OUString* p1, OUString* p2 ) bool mbIgnoreCase;
Compare( OUString* p1, OUString* p2 ) :
mbIgnoreCase(true)
{ {
pVal[0] = p1; pVal[0] = p1;
pVal[1] = p2; pVal[1] = p2;
......
...@@ -36,6 +36,13 @@ class ScInterpreter; ...@@ -36,6 +36,13 @@ class ScInterpreter;
class SvNumberFormatter; class SvNumberFormatter;
class ScMatrixImpl; class ScMatrixImpl;
namespace sc {
struct Compare;
struct CompareOptions;
}
/** /**
* Try NOT to use this struct. This struct should go away in a hopefully * Try NOT to use this struct. This struct should go away in a hopefully
* not so distant futture. * not so distant futture.
...@@ -394,6 +401,9 @@ public: ...@@ -394,6 +401,9 @@ public:
double GetMaxValue( bool bTextAsZero ) const; double GetMaxValue( bool bTextAsZero ) const;
double GetMinValue( bool bTextAsZero ) const; double GetMinValue( bool bTextAsZero ) const;
void CompareMatrix(
ScMatrix& rResMat, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions = NULL ) const;
void GetDoubleArray( std::vector<double>& rArray ) const; void GetDoubleArray( std::vector<double>& rArray ) const;
void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const; void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const;
......
...@@ -793,6 +793,7 @@ double ScInterpreter::Compare() ...@@ -793,6 +793,7 @@ double ScInterpreter::Compare()
{ {
OUString aVal1, aVal2; OUString aVal1, aVal2;
sc::Compare aComp( &aVal1, &aVal2 ); sc::Compare aComp( &aVal1, &aVal2 );
aComp.mbIgnoreCase = pDok->GetDocOptions().IsIgnoreCase();
for( short i = 1; i >= 0; i-- ) for( short i = 1; i >= 0; i-- )
{ {
switch ( GetRawStackType() ) switch ( GetRawStackType() )
...@@ -882,6 +883,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( sc::CompareOptions* pOptions ) ...@@ -882,6 +883,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( sc::CompareOptions* pOptions )
{ {
OUString aVal1, aVal2; OUString aVal1, aVal2;
sc::Compare aComp( &aVal1, &aVal2 ); sc::Compare aComp( &aVal1, &aVal2 );
aComp.mbIgnoreCase = pDok->GetDocOptions().IsIgnoreCase();
sc::RangeMatrix aMat[2]; sc::RangeMatrix aMat[2];
ScAddress aAdr; ScAddress aAdr;
for( short i = 1; i >= 0; i-- ) for( short i = 1; i >= 0; i-- )
...@@ -983,7 +985,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( sc::CompareOptions* pOptions ) ...@@ -983,7 +985,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( sc::CompareOptions* pOptions )
} }
else if (aMat[0].mpMat || aMat[1].mpMat) else if (aMat[0].mpMat || aMat[1].mpMat)
{ {
short i = ( aMat[0].mpMat ? 0 : 1); size_t i = ( aMat[0].mpMat ? 0 : 1);
SCSIZE nC, nR; SCSIZE nC, nR;
aMat[i].mpMat->GetDimensions(nC, nR); aMat[i].mpMat->GetDimensions(nC, nR);
aRes.mpMat = GetNewMat(nC, nR, false); aRes.mpMat = GetNewMat(nC, nR, false);
...@@ -999,46 +1001,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( sc::CompareOptions* pOptions ) ...@@ -999,46 +1001,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( sc::CompareOptions* pOptions )
ScMatrix& rMat = *aMat[i].mpMat; ScMatrix& rMat = *aMat[i].mpMat;
ScMatrix& rResMat = *aRes.mpMat; ScMatrix& rResMat = *aRes.mpMat;
ScMatrix::PosRef pMatPos(rMat.GetPosition(0, 0)); rMat.CompareMatrix(rResMat, aComp, i, pOptions);
ScMatrixValue aVal;
std::vector<double> aResMatValues;
aResMatValues.reserve(nC*nR);
for (size_t j = 0, n = nC*nR; j < n; ++j)
{
aVal = rMat.Get(*pMatPos);
switch (aVal.nType)
{
case SC_MATVAL_VALUE:
case SC_MATVAL_BOOLEAN:
{
aComp.bVal[i] = true;
aComp.nVal[i] = aVal.fVal;
aComp.bEmpty[i] = false;
}
break;
case SC_MATVAL_STRING:
{
aComp.bVal[i] = false;
*aComp.pVal[i] = aVal.aStr.getString();
aComp.bEmpty[i] = false;
}
break;
case SC_MATVAL_EMPTY:
case SC_MATVAL_EMPTYPATH:
{
aComp.bVal[i] = false;
*aComp.pVal[i] = svl::SharedString::getEmptyString().getString();
aComp.bEmpty[i] = aVal.nType == SC_MATVAL_EMPTY;
}
break;
default:
;
}
aResMatValues.push_back(sc::CompareFunc(pDok->GetDocOptions().IsIgnoreCase(), aComp, pOptions));
rMat.NextPosition(*pMatPos);
}
rResMat.PutDouble(&aResMatValues[0], aResMatValues.size(), 0, 0);
} }
} }
nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL; nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "formula/errorcodes.hxx" #include "formula/errorcodes.hxx"
#include "interpre.hxx" #include "interpre.hxx"
#include "mtvelements.hxx" #include "mtvelements.hxx"
#include "compare.hxx"
#include <svl/zforlist.hxx> #include <svl/zforlist.hxx>
#include "svl/sharedstring.hxx" #include "svl/sharedstring.hxx"
...@@ -264,6 +265,9 @@ public: ...@@ -264,6 +265,9 @@ public:
double GetMaxValue( bool bTextAsZero ) const; double GetMaxValue( bool bTextAsZero ) const;
double GetMinValue( bool bTextAsZero ) const; double GetMinValue( bool bTextAsZero ) const;
void CompareMatrix( ScMatrix& rResMat, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) const;
void GetDoubleArray( std::vector<double>& rArray ) const; void GetDoubleArray( std::vector<double>& rArray ) const;
void MergeDoubleArray( std::vector<double>& rArray, ScMatrix::Op eOp ) const; void MergeDoubleArray( std::vector<double>& rArray, ScMatrix::Op eOp ) const;
...@@ -1318,6 +1322,97 @@ public: ...@@ -1318,6 +1322,97 @@ public:
} }
}; };
class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type, void>
{
sc::Compare& mrComp;
size_t mnMatPos;
sc::CompareOptions* mpOptions;
std::vector<double> maResValues;
void compare()
{
maResValues.push_back(sc::CompareFunc(mrComp.mbIgnoreCase, mrComp, mpOptions));
}
public:
CompareMatrixFunc( size_t nResSize, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) :
mrComp(rComp), mnMatPos(nMatPos), mpOptions(pOptions)
{
maResValues.reserve(nResSize);
}
void operator() (const MatrixImplType::element_block_node_type& node)
{
using namespace mdds::mtv;
switch (node.type)
{
case mdds::mtm::element_numeric:
{
typedef MatrixImplType::numeric_block_type block_type;
block_type::const_iterator it = block_type::begin(*node.data);
block_type::const_iterator itEnd = block_type::end(*node.data);
for (; it != itEnd; ++it)
{
mrComp.bVal[mnMatPos] = true;
mrComp.nVal[mnMatPos] = *it;
mrComp.bEmpty[mnMatPos] = false;
compare();
}
}
break;
case mdds::mtm::element_boolean:
{
typedef MatrixImplType::boolean_block_type block_type;
block_type::const_iterator it = block_type::begin(*node.data);
block_type::const_iterator itEnd = block_type::end(*node.data);
for (; it != itEnd; ++it)
{
mrComp.bVal[mnMatPos] = true;
mrComp.nVal[mnMatPos] = *it;
mrComp.bEmpty[mnMatPos] = false;
compare();
}
}
break;
case mdds::mtm::element_string:
{
typedef MatrixImplType::string_block_type block_type;
block_type::const_iterator it = block_type::begin(*node.data);
block_type::const_iterator itEnd = block_type::end(*node.data);
for (; it != itEnd; ++it)
{
const svl::SharedString& rStr = *it;
mrComp.bVal[mnMatPos] = false;
*mrComp.pVal[mnMatPos] = rStr.getString();
mrComp.bEmpty[mnMatPos] = false;
compare();
}
}
break;
case mdds::mtm::element_empty:
{
mrComp.bVal[mnMatPos] = false;
*mrComp.pVal[mnMatPos] = svl::SharedString::getEmptyString().getString();
mrComp.bEmpty[mnMatPos] = true;
for (size_t i = 0; i < node.size; ++i)
compare();
}
default:
;
}
}
const std::vector<double>& getValues() const
{
return maResValues;
}
};
class ToDoubleArray : std::unary_function<MatrixImplType::element_block_type, void> class ToDoubleArray : std::unary_function<MatrixImplType::element_block_type, void>
{ {
std::vector<double> maArray; std::vector<double> maArray;
...@@ -1496,6 +1591,20 @@ double ScMatrixImpl::GetMinValue( bool bTextAsZero ) const ...@@ -1496,6 +1591,20 @@ double ScMatrixImpl::GetMinValue( bool bTextAsZero ) const
return aFunc.getValue(); return aFunc.getValue();
} }
void ScMatrixImpl::CompareMatrix(
ScMatrix& rResMat, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) const
{
MatrixImplType::size_pair_type aSize = maMat.size();
size_t nSize = aSize.column * aSize.row;
CompareMatrixFunc aFunc(nSize, rComp, nMatPos, pOptions);
maMat.walk(aFunc);
// We assume the result matrix has the same dimension as this matrix.
const std::vector<double>& rResVal = aFunc.getValues();
if (nSize == rResVal.size())
rResMat.PutDouble(&rResVal[0], rResVal.size(), 0, 0);
}
void ScMatrixImpl::GetDoubleArray( std::vector<double>& rArray ) const void ScMatrixImpl::GetDoubleArray( std::vector<double>& rArray ) const
{ {
MatrixImplType::size_pair_type aSize = maMat.size(); MatrixImplType::size_pair_type aSize = maMat.size();
...@@ -2006,6 +2115,11 @@ double ScMatrix::GetMinValue( bool bTextAsZero ) const ...@@ -2006,6 +2115,11 @@ double ScMatrix::GetMinValue( bool bTextAsZero ) const
return pImpl->GetMinValue(bTextAsZero); return pImpl->GetMinValue(bTextAsZero);
} }
void ScMatrix::CompareMatrix( ScMatrix& rResMat, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) const
{
pImpl->CompareMatrix(rResMat, rComp, nMatPos, pOptions);
}
void ScMatrix::GetDoubleArray( std::vector<double>& rArray ) const void ScMatrix::GetDoubleArray( std::vector<double>& rArray ) const
{ {
pImpl->GetDoubleArray(rArray); pImpl->GetDoubleArray(rArray);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment