[Libreoffice-commits] core.git: Branch 'private/kohei/calc-shared-string' - sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed Oct 16 08:39:43 PDT 2013


 sc/source/core/data/column2.cxx |  132 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 126 insertions(+), 6 deletions(-)

New commits:
commit bae944cd7c4fb2804e9a2687a842f5a072b270bf
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Oct 16 11:40:06 2013 -0400

    Redo vector ref array fetching for ranges starting with a numeric cell.
    
    The test now passes.
    
    Change-Id: I84e98e326be9cab175ecb95dbb4db4c535bca6d2

diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 32a4ded..f5be76f 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2178,6 +2178,129 @@ bool appendDouble(
     return false;
 }
 
+formula::VectorRefArray appendToNumBlock(
+    ScDocument* pDoc, sc::FormulaGroupContext& rCxt, size_t nPos,
+    size_t nLenRequested, sc::CellStoreType::iterator it, const sc::CellStoreType::iterator& itEnd )
+{
+    sc::FormulaGroupContext::NumArrayType& rNumArray = rCxt.maNumArrays.back();
+    sc::FormulaGroupContext::StrArrayType* pStrArray = NULL;
+    svl::SharedStringPool& rPool = pDoc->GetSharedStringPool();
+    size_t nLenRemain = nLenRequested - nPos;
+
+    for (; it != itEnd; ++it)
+    {
+        switch (it->type)
+        {
+            case sc::element_type_string:
+            {
+                sc::string_block::iterator itData, itDataEnd;
+                getBlockIterators<sc::string_block>(it, nLenRemain, itData, itDataEnd);
+
+                if (!pStrArray)
+                {
+                    rCxt.maStrArrays.push_back(
+                        new sc::FormulaGroupContext::StrArrayType(nLenRequested, NULL));
+                    pStrArray = &rCxt.maStrArrays.back();
+                }
+
+                for (; itData != itDataEnd; ++itData, ++nPos)
+                    (*pStrArray)[nPos] = itData->getDataIgnoreCase();
+            }
+            break;
+            case sc::element_type_edittext:
+            {
+                sc::edittext_block::iterator itData, itDataEnd;
+                getBlockIterators<sc::edittext_block>(it, nLenRemain, itData, itDataEnd);
+
+                if (!pStrArray)
+                {
+                    rCxt.maStrArrays.push_back(
+                        new sc::FormulaGroupContext::StrArrayType(nLenRequested, NULL));
+                    pStrArray = &rCxt.maStrArrays.back();
+                }
+
+                for (; itData != itDataEnd; ++itData, ++nPos)
+                {
+                    OUString aStr = ScEditUtil::GetString(**itData, pDoc);
+                    (*pStrArray)[nPos] = rPool.intern(aStr).getDataIgnoreCase();
+                }
+            }
+            break;
+            case sc::element_type_formula:
+            {
+                sc::formula_block::iterator itData, itDataEnd;
+                getBlockIterators<sc::formula_block>(it, nLenRemain, itData, itDataEnd);
+
+                for (; itData != itDataEnd; ++itData, ++nPos)
+                {
+                    ScFormulaCell& rFC = **itData;
+                    sc::FormulaResultValue aRes = rFC.GetResult();
+                    if (aRes.meType == sc::FormulaResultValue::Invalid || aRes.mnError)
+                    {
+                        if (aRes.mnError == ScErrorCodes::errCircularReference)
+                        {
+                            // This cell needs to be recalculated on next visit.
+                            rFC.SetErrCode(0);
+                            rFC.SetDirtyVar();
+                        }
+                        return formula::VectorRefArray();
+                    }
+
+                    if (aRes.meType == sc::FormulaResultValue::Value)
+                        rNumArray[nPos] = aRes.mfValue;
+                    else
+                    {
+                        if (!pStrArray)
+                        {
+                            rCxt.maStrArrays.push_back(
+                                new sc::FormulaGroupContext::StrArrayType(nLenRequested, NULL));
+                            pStrArray = &rCxt.maStrArrays.back();
+                        }
+
+                        (*pStrArray)[nPos] = aRes.maString.getDataIgnoreCase();
+                    }
+                }
+            }
+            break;
+            case sc::element_type_empty:
+            {
+                if (nLenRemain > it->size)
+                {
+                    nPos += it->size;
+                    nLenRemain -= it->size;
+                }
+                else
+                {
+                    nPos = nLenRequested;
+                    nLenRemain = 0;
+                }
+            }
+            break;
+            case sc::element_type_numeric:
+            {
+                sc::numeric_block::iterator itData, itDataEnd;
+                getBlockIterators<sc::numeric_block>(it, nLenRemain, itData, itDataEnd);
+
+                for (; itData != itDataEnd; ++itData, ++nPos)
+                    rNumArray[nPos] = *itData;
+            }
+            break;
+            default:
+                return formula::VectorRefArray();
+        }
+
+        if (!nLenRemain)
+        {
+            if (pStrArray)
+                return formula::VectorRefArray(&rNumArray[0], &(*pStrArray)[0]);
+            else
+                return formula::VectorRefArray(&rNumArray[0]);
+        }
+    }
+
+    return formula::VectorRefArray();
+}
+
 formula::VectorRefArray appendToStringBlock(
     ScDocument* pDoc, sc::FormulaGroupContext& rCxt, size_t nPos,
     size_t nLenRequested, sc::CellStoreType::iterator it, const sc::CellStoreType::iterator& itEnd )
@@ -2343,7 +2466,7 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( sc::FormulaGroupContext&
 
     size_t nLenRequested = nRow2 - nRow1 + 1;
     sc::CellStoreType::position_type aPos = maCells.position(nRow1);
-    size_t nLen = aPos.first->size - aPos.second;
+    size_t nLen = aPos.first->size - aPos.second; // length of data from first block
     switch (aPos.first->type)
     {
         case sc::element_type_numeric:
@@ -2362,14 +2485,11 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( sc::FormulaGroupContext&
             std::advance(it, aPos.second);
             rCxt.maNumArrays.push_back(new sc::FormulaGroupContext::NumArrayType(it, itEnd));
             sc::FormulaGroupContext::NumArrayType& rArray = rCxt.maNumArrays.back();
-            rArray.reserve(nLenRequested);
+            rArray.resize(nLenRequested, fNan); // allocate to the requested length.
 
             // Fill the remaining array with values from the following blocks.
             ++aPos.first;
-            if (!appendDouble(rArray, nLenRequested - nLen, aPos.first, maCells.end()))
-                return formula::VectorRefArray();
-
-            return formula::VectorRefArray(&rArray[0]);
+            return appendToNumBlock(pDocument, rCxt, nLen, nLenRequested, aPos.first, maCells.end());
         }
         break;
         case sc::element_type_formula:


More information about the Libreoffice-commits mailing list