[Libreoffice-commits] core.git: Branch 'private/kohei/formula-opencl-work' - formula/source include/formula sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Mon Sep 9 15:00:26 PDT 2013


 formula/source/core/api/vectortoken.cxx |    2 
 include/formula/vectortoken.hxx         |    4 -
 sc/inc/formulagroup.hxx                 |    7 ++
 sc/source/core/data/column2.cxx         |   10 +++-
 sc/source/core/tool/formulagroup.cxx    |   78 ++++++++++++++++++++++++++++++--
 5 files changed, 92 insertions(+), 9 deletions(-)

New commits:
commit 46a50d1faed9cf4813f52bb3b9b3ea1418f8a0c5
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Sep 9 18:00:08 2013 -0400

    Correctly handle empty cells for string arrays too.
    
    Because we need to make a distinction between an empty cell and a string
    cell containing zero-length string, I decided to switch to using
    rtl_uString* array and use NULL values as empty cells.
    
    Change-Id: I5bedb593507f34782e41a8a900602d445e5b1f6f

diff --git a/formula/source/core/api/vectortoken.cxx b/formula/source/core/api/vectortoken.cxx
index 557e0c0..b752f5d 100644
--- a/formula/source/core/api/vectortoken.cxx
+++ b/formula/source/core/api/vectortoken.cxx
@@ -13,7 +13,7 @@ namespace formula {
 
 VectorRefArray::VectorRefArray() : mpNumericArray(NULL), mbNumeric(true) {}
 VectorRefArray::VectorRefArray( const double* pArray ) : mpNumericArray(pArray), mbNumeric(true) {}
-VectorRefArray::VectorRefArray( const OUString* pArray ) : mpStringArray(pArray), mbNumeric(false) {}
+VectorRefArray::VectorRefArray( rtl_uString** pArray ) : mpStringArray(pArray), mbNumeric(false) {}
 
 SingleVectorRefToken::SingleVectorRefToken( const double* pArray, size_t nLength ) :
     FormulaToken(svSingleVectorRef, ocPush), maArray(pArray), mnArrayLength(nLength) {}
diff --git a/include/formula/vectortoken.hxx b/include/formula/vectortoken.hxx
index 5186ca5..9bc82f3 100644
--- a/include/formula/vectortoken.hxx
+++ b/include/formula/vectortoken.hxx
@@ -18,14 +18,14 @@ struct FORMULA_DLLPUBLIC VectorRefArray
 {
     union {
         const double* mpNumericArray;
-        const OUString* mpStringArray;
+        rtl_uString** mpStringArray;
     };
 
     bool mbNumeric;
 
     VectorRefArray();
     VectorRefArray( const double* pArray );
-    VectorRefArray( const OUString* pArray );
+    VectorRefArray( rtl_uString** pArray );
 };
 
 /**
diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index 776b24d..f57b237 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -15,6 +15,7 @@
 
 #include <boost/noncopyable.hpp>
 #include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/unordered_set.hpp>
 
 class ScDocument;
 class ScTokenArray;
@@ -23,13 +24,17 @@ namespace sc {
 
 struct FormulaGroupContext : boost::noncopyable
 {
+    typedef boost::unordered_set<OUString, OUStringHash> StrHashType;
     typedef std::vector<double> NumArrayType;
-    typedef std::vector<OUString> StrArrayType;
+    typedef std::vector<rtl_uString*> StrArrayType;
     typedef boost::ptr_vector<NumArrayType> NumArrayStoreType;
     typedef boost::ptr_vector<StrArrayType> StrArrayStoreType;
 
+    StrHashType maStrPool;
     NumArrayStoreType maNumArrays;
     StrArrayStoreType maStrArrays;
+
+    rtl_uString* intern( const OUString& rStr );
 };
 
 /**
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 34ecbb2..7a97972 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2256,8 +2256,16 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( sc::FormulaGroupContext&
             if (nLenRequested <= nLen)
             {
                 // Requested length fits a single block.
+                rCxt.maStrArrays.push_back(new sc::FormulaGroupContext::StrArrayType);
+                sc::FormulaGroupContext::StrArrayType& rArray = rCxt.maStrArrays.back();
+                rArray.reserve(nLenRequested);
+
                 const OUString* p = &sc::string_block::at(*aPos.first->data, aPos.second);
-                return formula::VectorRefArray(p);
+                const OUString* pEnd = p + nLenRequested;
+                for (; p != pEnd; ++p)
+                    rArray.push_back(rCxt.intern(*p));
+
+                return formula::VectorRefArray(&rArray[0]);
             }
 
             // TODO: handle cases where the requested length goes beyond the
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index f6a1dff..0b37b97 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -29,6 +29,23 @@
 
 namespace sc {
 
+rtl_uString* FormulaGroupContext::intern( const OUString& rStr )
+{
+    StrHashType::iterator it = maStrPool.find(rStr);
+    if (it == maStrPool.end())
+    {
+        // Not yet in the pool.
+        std::pair<StrHashType::iterator, bool> r = maStrPool.insert(rStr.intern());
+        if (!r.second)
+            // Insertion failed.
+            return NULL;
+
+        it = r.first;
+    }
+
+    return it->pData;
+}
+
 namespace {
 
 /**
@@ -63,7 +80,49 @@ void fillMatrix( ScMatrix& rMat, size_t nCol, const double* pNums, size_t nLen )
     {
         // Flush last non-NaN segment to the matrix.
         rMat.PutDouble(pHead, p - pHead, nCol, pHead - pNums);
-        pHead = NULL;
+    }
+}
+
+void fillMatrix( ScMatrix& rMat, size_t nCol, rtl_uString** pStrs, size_t nLen )
+{
+    rtl_uString** p = pStrs;
+    rtl_uString** pEnd = p + nLen;
+    rtl_uString** pHead = NULL;
+    for (; p != pEnd; ++p)
+    {
+        if (*p)
+        {
+            if (!pHead)
+                // Store the first non-empty string position.
+                pHead = p;
+
+            continue;
+        }
+
+        if (pHead)
+        {
+            // Flush this non-empty segment to the matrix.
+            size_t nOffset = pHead - pStrs;
+            std::vector<OUString> aStrs;
+            aStrs.reserve(p - pHead);
+            for (; pHead != p; ++pHead)
+                aStrs.push_back(OUString(*pHead));
+
+            rMat.PutString(&aStrs[0], aStrs.size(), nCol, nOffset);
+            pHead = NULL;
+        }
+    }
+
+    if (pHead)
+    {
+        // Flush last non-empty segment to the matrix.
+        size_t nOffset = pHead - pStrs;
+        std::vector<OUString> aStrs;
+        aStrs.reserve(p - pHead);
+        for (; pHead != p; ++pHead)
+            aStrs.push_back(OUString(*pHead));
+
+        rMat.PutString(&aStrs[0], aStrs.size(), nCol, nOffset);
     }
 }
 
@@ -124,7 +183,14 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
                             aCode2.AddDouble(fVal);
                     }
                     else
-                        aCode2.AddString(static_cast<size_t>(i) < p2->GetArrayLength() ? rArray.mpStringArray[i] : OUString());
+                    {
+                        rtl_uString* pStr = NULL;
+                        if (static_cast<size_t>(i) < p2->GetArrayLength())
+                            pStr = rArray.mpStringArray[i];
+
+                        if (pStr)
+                            aCode2.AddString(OUString(pStr));
+                    }
                 }
                 break;
                 case formula::svDoubleVectorRef:
@@ -138,6 +204,10 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
                         nRowEnd += i;
                     size_t nRowSize = nRowEnd - nRowStart + 1;
                     ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize));
+                    if (p2->GetArrayLength() < nRowSize)
+                        // Data array is shorter than the row size of the reference. Truncate it.
+                        nRowSize = p2->GetArrayLength();
+
                     for (size_t nCol = 0; nCol < nColSize; ++nCol)
                     {
                         const formula::VectorRefArray& rArray = rArrays[nCol];
@@ -149,9 +219,9 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
                         }
                         else
                         {
-                            const OUString* pStrs = rArray.mpStringArray;
+                            rtl_uString** pStrs = rArray.mpStringArray;
                             pStrs += nRowStart;
-                            pMat->PutString(pStrs, nRowSize, nCol, 0);
+                            fillMatrix(*pMat, nCol, pStrs, nRowSize);
                         }
                     }
 


More information about the Libreoffice-commits mailing list