1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file
5b3f79822SAndrew Rist * distributed with this work for additional information
6b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist * software distributed under the License is distributed on an
15b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist * KIND, either express or implied. See the License for the
17b3f79822SAndrew Rist * specific language governing permissions and limitations
18b3f79822SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20b3f79822SAndrew Rist *************************************************************/
21b3f79822SAndrew Rist
22b3f79822SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include "compressedarray.hxx"
28cdf0e10cSrcweir #include "address.hxx"
29cdf0e10cSrcweir
30cdf0e10cSrcweir #include <algorithm>
31cdf0e10cSrcweir
32cdf0e10cSrcweir template< typename A, typename D >
ScCompressedArray(A nMaxAccessP,const D & rValue,size_t nDeltaP)33cdf0e10cSrcweir ScCompressedArray<A,D>::ScCompressedArray( A nMaxAccessP, const D& rValue,
34cdf0e10cSrcweir size_t nDeltaP )
35cdf0e10cSrcweir : nCount(1)
36cdf0e10cSrcweir , nLimit(1)
37cdf0e10cSrcweir , nDelta( nDeltaP > 0 ? nDeltaP : 1)
38cdf0e10cSrcweir , pData( new DataEntry[1])
39cdf0e10cSrcweir , nMaxAccess( nMaxAccessP)
40cdf0e10cSrcweir {
41cdf0e10cSrcweir pData[0].aValue = rValue;
42cdf0e10cSrcweir pData[0].nEnd = nMaxAccess;
43cdf0e10cSrcweir }
44cdf0e10cSrcweir
45cdf0e10cSrcweir
46cdf0e10cSrcweir template< typename A, typename D >
ScCompressedArray(A nMaxAccessP,const D * pDataArray,size_t nDataCount)47cdf0e10cSrcweir ScCompressedArray<A,D>::ScCompressedArray( A nMaxAccessP, const D* pDataArray,
48cdf0e10cSrcweir size_t nDataCount )
49cdf0e10cSrcweir : nCount(0)
50cdf0e10cSrcweir , nLimit( nDataCount)
51cdf0e10cSrcweir , nDelta( nScCompressedArrayDelta)
52cdf0e10cSrcweir , pData( new DataEntry[nDataCount])
53cdf0e10cSrcweir , nMaxAccess( nMaxAccessP)
54cdf0e10cSrcweir {
55cdf0e10cSrcweir D aValue = pDataArray[0];
56cdf0e10cSrcweir for (size_t j=0; j<nDataCount; ++j)
57cdf0e10cSrcweir {
58cdf0e10cSrcweir if (!(aValue == pDataArray[j]))
59cdf0e10cSrcweir {
60cdf0e10cSrcweir pData[nCount].aValue = aValue;
61cdf0e10cSrcweir pData[nCount].nEnd = j-1;
62cdf0e10cSrcweir ++nCount;
63cdf0e10cSrcweir aValue = pDataArray[j];
64cdf0e10cSrcweir }
65cdf0e10cSrcweir }
66cdf0e10cSrcweir pData[nCount].aValue = aValue;
67cdf0e10cSrcweir pData[nCount].nEnd = nMaxAccess;
68cdf0e10cSrcweir ++nCount;
69cdf0e10cSrcweir Resize( nCount);
70cdf0e10cSrcweir }
71cdf0e10cSrcweir
72cdf0e10cSrcweir
73cdf0e10cSrcweir template< typename A, typename D >
~ScCompressedArray()74cdf0e10cSrcweir ScCompressedArray<A,D>::~ScCompressedArray()
75cdf0e10cSrcweir {
76cdf0e10cSrcweir delete[] pData;
77cdf0e10cSrcweir }
78cdf0e10cSrcweir
79cdf0e10cSrcweir
80cdf0e10cSrcweir template< typename A, typename D >
Resize(size_t nNewLimit)81cdf0e10cSrcweir void ScCompressedArray<A,D>::Resize( size_t nNewLimit)
82cdf0e10cSrcweir {
83cdf0e10cSrcweir if ((nCount <= nNewLimit && nNewLimit < nLimit) || nLimit < nNewLimit)
84cdf0e10cSrcweir {
85cdf0e10cSrcweir nLimit = nNewLimit;
86cdf0e10cSrcweir DataEntry* pNewData = new DataEntry[nLimit];
87cdf0e10cSrcweir memcpy( pNewData, pData, nCount*sizeof(DataEntry));
88cdf0e10cSrcweir delete[] pData;
89cdf0e10cSrcweir pData = pNewData;
90cdf0e10cSrcweir }
91cdf0e10cSrcweir }
92cdf0e10cSrcweir
93cdf0e10cSrcweir
94cdf0e10cSrcweir template< typename A, typename D >
Search(A nAccess) const95cdf0e10cSrcweir size_t ScCompressedArray<A,D>::Search( A nAccess ) const
96cdf0e10cSrcweir {
97cdf0e10cSrcweir if (nAccess == 0)
98cdf0e10cSrcweir return 0;
99cdf0e10cSrcweir
100cdf0e10cSrcweir long nLo = 0;
101cdf0e10cSrcweir long nHi = static_cast<long>(nCount) - 1;
102cdf0e10cSrcweir long nStart = 0;
103cdf0e10cSrcweir long nEnd = 0;
104cdf0e10cSrcweir long i = 0;
105cdf0e10cSrcweir bool bFound = (nCount == 1);
106cdf0e10cSrcweir while (!bFound && nLo <= nHi)
107cdf0e10cSrcweir {
108cdf0e10cSrcweir i = (nLo + nHi) / 2;
109cdf0e10cSrcweir if (i > 0)
110cdf0e10cSrcweir nStart = (long) pData[i - 1].nEnd;
111cdf0e10cSrcweir else
112cdf0e10cSrcweir nStart = -1;
113cdf0e10cSrcweir nEnd = (long) pData[i].nEnd;
114cdf0e10cSrcweir if (nEnd < (long) nAccess)
115cdf0e10cSrcweir nLo = ++i;
116cdf0e10cSrcweir else
117cdf0e10cSrcweir if (nStart >= (long) nAccess)
118cdf0e10cSrcweir nHi = --i;
119cdf0e10cSrcweir else
120cdf0e10cSrcweir bFound = true;
121cdf0e10cSrcweir }
122cdf0e10cSrcweir return (bFound ? static_cast<size_t>(i) : (nAccess < 0 ? 0 : nCount-1));
123cdf0e10cSrcweir }
124cdf0e10cSrcweir
125cdf0e10cSrcweir
126cdf0e10cSrcweir template< typename A, typename D >
SetValue(A nStart,A nEnd,const D & rValue)127cdf0e10cSrcweir void ScCompressedArray<A,D>::SetValue( A nStart, A nEnd, const D& rValue )
128cdf0e10cSrcweir {
129cdf0e10cSrcweir if (0 <= nStart && nStart <= nMaxAccess && 0 <= nEnd && nEnd <= nMaxAccess
130cdf0e10cSrcweir && nStart <= nEnd)
131cdf0e10cSrcweir {
132cdf0e10cSrcweir if ((nStart == 0) && (nEnd == nMaxAccess))
133cdf0e10cSrcweir Reset( rValue);
134cdf0e10cSrcweir else
135cdf0e10cSrcweir {
136cdf0e10cSrcweir // Create a temporary copy in case we got a reference passed that
137cdf0e10cSrcweir // points to a part of the array to be reallocated.
138cdf0e10cSrcweir D aNewVal( rValue);
139cdf0e10cSrcweir size_t nNeeded = nCount + 2;
140cdf0e10cSrcweir if (nLimit < nNeeded)
141cdf0e10cSrcweir {
142cdf0e10cSrcweir nLimit += nDelta;
143cdf0e10cSrcweir if (nLimit < nNeeded)
144cdf0e10cSrcweir nLimit = nNeeded;
145cdf0e10cSrcweir DataEntry* pNewData = new DataEntry[nLimit];
146cdf0e10cSrcweir memcpy( pNewData, pData, nCount*sizeof(DataEntry));
147cdf0e10cSrcweir delete[] pData;
148cdf0e10cSrcweir pData = pNewData;
149cdf0e10cSrcweir }
150cdf0e10cSrcweir
151cdf0e10cSrcweir size_t ni; // number of leading entries
152cdf0e10cSrcweir size_t nInsert; // insert position (nMaxAccess+1 := no insert)
153cdf0e10cSrcweir bool bCombined = false;
154cdf0e10cSrcweir bool bSplit = false;
155cdf0e10cSrcweir if (nStart > 0)
156cdf0e10cSrcweir {
157cdf0e10cSrcweir // skip leading
158cdf0e10cSrcweir ni = Search( nStart);
159cdf0e10cSrcweir
160cdf0e10cSrcweir nInsert = nMaxAccess+1;
161cdf0e10cSrcweir if (!(pData[ni].aValue == aNewVal))
162cdf0e10cSrcweir {
163cdf0e10cSrcweir if (ni == 0 || (pData[ni-1].nEnd < nStart - 1))
164cdf0e10cSrcweir { // may be a split or a simple insert or just a shrink,
165cdf0e10cSrcweir // row adjustment is done further down
166cdf0e10cSrcweir if (pData[ni].nEnd > nEnd)
167cdf0e10cSrcweir bSplit = true;
168cdf0e10cSrcweir ni++;
169cdf0e10cSrcweir nInsert = ni;
170cdf0e10cSrcweir }
171cdf0e10cSrcweir else if (ni > 0 && pData[ni-1].nEnd == nStart - 1)
172cdf0e10cSrcweir nInsert = ni;
173cdf0e10cSrcweir }
174cdf0e10cSrcweir if (ni > 0 && pData[ni-1].aValue == aNewVal)
175cdf0e10cSrcweir { // combine
176cdf0e10cSrcweir pData[ni-1].nEnd = nEnd;
177cdf0e10cSrcweir nInsert = nMaxAccess+1;
178cdf0e10cSrcweir bCombined = true;
179cdf0e10cSrcweir }
180cdf0e10cSrcweir }
181cdf0e10cSrcweir else
182cdf0e10cSrcweir {
183cdf0e10cSrcweir nInsert = 0;
184cdf0e10cSrcweir ni = 0;
185cdf0e10cSrcweir }
186cdf0e10cSrcweir
187cdf0e10cSrcweir size_t nj = ni; // stop position of range to replace
188cdf0e10cSrcweir while (nj < nCount && pData[nj].nEnd <= nEnd)
189cdf0e10cSrcweir nj++;
190cdf0e10cSrcweir if (!bSplit)
191cdf0e10cSrcweir {
192cdf0e10cSrcweir if (nj < nCount && pData[nj].aValue == aNewVal)
193cdf0e10cSrcweir { // combine
194cdf0e10cSrcweir if (ni > 0)
195cdf0e10cSrcweir {
196cdf0e10cSrcweir if (pData[ni-1].aValue == aNewVal)
197cdf0e10cSrcweir { // adjacent entries
198cdf0e10cSrcweir pData[ni-1].nEnd = pData[nj].nEnd;
199cdf0e10cSrcweir nj++;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir else if (ni == nInsert)
202cdf0e10cSrcweir pData[ni-1].nEnd = nStart - 1; // shrink
203cdf0e10cSrcweir }
204cdf0e10cSrcweir nInsert = nMaxAccess+1;
205cdf0e10cSrcweir bCombined = true;
206cdf0e10cSrcweir }
207cdf0e10cSrcweir else if (ni > 0 && ni == nInsert)
208cdf0e10cSrcweir pData[ni-1].nEnd = nStart - 1; // shrink
209cdf0e10cSrcweir }
210cdf0e10cSrcweir if (ni < nj)
211cdf0e10cSrcweir { // remove middle entries
212cdf0e10cSrcweir if (!bCombined)
213cdf0e10cSrcweir { // replace one entry
214cdf0e10cSrcweir pData[ni].nEnd = nEnd;
215cdf0e10cSrcweir pData[ni].aValue = aNewVal;
216cdf0e10cSrcweir ni++;
217cdf0e10cSrcweir nInsert = nMaxAccess+1;
218cdf0e10cSrcweir }
219cdf0e10cSrcweir if (ni < nj)
220cdf0e10cSrcweir { // remove entries
221cdf0e10cSrcweir memmove( pData + ni, pData + nj,
222cdf0e10cSrcweir (nCount - nj) * sizeof(DataEntry));
223cdf0e10cSrcweir nCount -= nj - ni;
224cdf0e10cSrcweir }
225cdf0e10cSrcweir }
226cdf0e10cSrcweir
227cdf0e10cSrcweir if (nInsert < static_cast<size_t>(nMaxAccess+1))
228cdf0e10cSrcweir { // insert or append new entry
229cdf0e10cSrcweir if (nInsert <= nCount)
230cdf0e10cSrcweir {
231cdf0e10cSrcweir if (!bSplit)
232cdf0e10cSrcweir memmove( pData + nInsert + 1, pData + nInsert,
233cdf0e10cSrcweir (nCount - nInsert) * sizeof(DataEntry));
234cdf0e10cSrcweir else
235cdf0e10cSrcweir {
236cdf0e10cSrcweir memmove( pData + nInsert + 2, pData + nInsert,
237cdf0e10cSrcweir (nCount - nInsert) * sizeof(DataEntry));
238cdf0e10cSrcweir pData[nInsert+1] = pData[nInsert-1];
239cdf0e10cSrcweir nCount++;
240cdf0e10cSrcweir }
241cdf0e10cSrcweir }
242cdf0e10cSrcweir if (nInsert)
243cdf0e10cSrcweir pData[nInsert-1].nEnd = nStart - 1;
244cdf0e10cSrcweir pData[nInsert].nEnd = nEnd;
245cdf0e10cSrcweir pData[nInsert].aValue = aNewVal;
246cdf0e10cSrcweir nCount++;
247cdf0e10cSrcweir }
248cdf0e10cSrcweir }
249cdf0e10cSrcweir }
250cdf0e10cSrcweir }
251cdf0e10cSrcweir
252cdf0e10cSrcweir
253cdf0e10cSrcweir template< typename A, typename D >
CopyFrom(const ScCompressedArray<A,D> & rArray,A nStart,A nEnd,long nSourceDy)254cdf0e10cSrcweir void ScCompressedArray<A,D>::CopyFrom( const ScCompressedArray<A,D>& rArray, A nStart,
255cdf0e10cSrcweir A nEnd, long nSourceDy )
256cdf0e10cSrcweir {
257cdf0e10cSrcweir size_t nIndex;
258cdf0e10cSrcweir A nRegionEnd;
259cdf0e10cSrcweir for (A j=nStart; j<=nEnd; ++j)
260cdf0e10cSrcweir {
261cdf0e10cSrcweir const D& rValue = (j==nStart ?
262cdf0e10cSrcweir rArray.GetValue( j+nSourceDy, nIndex, nRegionEnd) :
263cdf0e10cSrcweir rArray.GetNextValue( nIndex, nRegionEnd));
264cdf0e10cSrcweir nRegionEnd -= nSourceDy;
265cdf0e10cSrcweir if (nRegionEnd > nEnd)
266cdf0e10cSrcweir nRegionEnd = nEnd;
267cdf0e10cSrcweir SetValue( j, nRegionEnd, rValue);
268cdf0e10cSrcweir j = nRegionEnd;
269cdf0e10cSrcweir }
270cdf0e10cSrcweir }
271cdf0e10cSrcweir
272cdf0e10cSrcweir
273cdf0e10cSrcweir template< typename A, typename D >
Insert(A nStart,size_t nAccessCount)274cdf0e10cSrcweir const D& ScCompressedArray<A,D>::Insert( A nStart, size_t nAccessCount )
275cdf0e10cSrcweir {
276cdf0e10cSrcweir size_t nIndex = Search( nStart);
277cdf0e10cSrcweir // No real insertion is needed, simply extend the one entry and adapt all
278cdf0e10cSrcweir // following. In case nStart points to the start row of an entry, extend
279cdf0e10cSrcweir // the previous entry (inserting before nStart).
280cdf0e10cSrcweir if (nIndex > 0 && pData[nIndex-1].nEnd+1 == nStart)
281cdf0e10cSrcweir --nIndex;
282cdf0e10cSrcweir const D& rValue = pData[nIndex].aValue; // the value "copied"
283cdf0e10cSrcweir do
284cdf0e10cSrcweir {
285cdf0e10cSrcweir pData[nIndex].nEnd += nAccessCount;
286cdf0e10cSrcweir if (pData[nIndex].nEnd >= nMaxAccess)
287cdf0e10cSrcweir {
288cdf0e10cSrcweir pData[nIndex].nEnd = nMaxAccess;
289cdf0e10cSrcweir nCount = nIndex + 1; // discard trailing entries
290cdf0e10cSrcweir }
291cdf0e10cSrcweir } while (++nIndex < nCount);
292cdf0e10cSrcweir return rValue;
293cdf0e10cSrcweir }
294cdf0e10cSrcweir
295cdf0e10cSrcweir
296cdf0e10cSrcweir template< typename A, typename D >
Remove(A nStart,size_t nAccessCount)297cdf0e10cSrcweir void ScCompressedArray<A,D>::Remove( A nStart, size_t nAccessCount )
298cdf0e10cSrcweir {
299cdf0e10cSrcweir A nEnd = nStart + nAccessCount - 1;
300cdf0e10cSrcweir size_t nIndex = Search( nStart);
301cdf0e10cSrcweir // equalize/combine/remove all entries in between
302cdf0e10cSrcweir if (nEnd > pData[nIndex].nEnd)
303cdf0e10cSrcweir SetValue( nStart, nEnd, pData[nIndex].aValue);
304cdf0e10cSrcweir // remove an exactly matching entry by shifting up all following by one
305cdf0e10cSrcweir if ((nStart == 0 || (nIndex > 0 && nStart == pData[nIndex-1].nEnd+1)) &&
306cdf0e10cSrcweir pData[nIndex].nEnd == nEnd && nIndex < nCount-1)
307cdf0e10cSrcweir {
308cdf0e10cSrcweir // In case removing an entry results in two adjacent entries with
309cdf0e10cSrcweir // identical data, combine them into one. This is also necessary to
310cdf0e10cSrcweir // make the algorithm used in SetValue() work correctly, it relies on
311cdf0e10cSrcweir // the fact that consecutive values actually differ.
312cdf0e10cSrcweir size_t nRemove;
313cdf0e10cSrcweir if (nIndex > 0 && pData[nIndex-1].aValue == pData[nIndex+1].aValue)
314cdf0e10cSrcweir {
315cdf0e10cSrcweir nRemove = 2;
316cdf0e10cSrcweir --nIndex;
317cdf0e10cSrcweir }
318cdf0e10cSrcweir else
319cdf0e10cSrcweir nRemove = 1;
320cdf0e10cSrcweir memmove( pData + nIndex, pData + nIndex + nRemove, (nCount - (nIndex +
321cdf0e10cSrcweir nRemove)) * sizeof(DataEntry));
322cdf0e10cSrcweir nCount -= nRemove;
323cdf0e10cSrcweir }
324cdf0e10cSrcweir // adjust end rows, nIndex still being valid
325cdf0e10cSrcweir do
326cdf0e10cSrcweir {
327cdf0e10cSrcweir pData[nIndex].nEnd -= nAccessCount;
328cdf0e10cSrcweir } while (++nIndex < nCount);
329cdf0e10cSrcweir pData[nCount-1].nEnd = nMaxAccess;
330cdf0e10cSrcweir }
331cdf0e10cSrcweir
332cdf0e10cSrcweir
333cdf0e10cSrcweir template< typename A, typename D >
GetLastUnequalAccess(A nStart,const D & rCompare)334cdf0e10cSrcweir A ScCompressedArray<A,D>::GetLastUnequalAccess( A nStart, const D& rCompare )
335cdf0e10cSrcweir {
336cdf0e10cSrcweir A nEnd = ::std::numeric_limits<A>::max();
337cdf0e10cSrcweir size_t nIndex = nCount-1;
338cdf0e10cSrcweir while (1)
339cdf0e10cSrcweir {
340cdf0e10cSrcweir if (pData[nIndex].aValue != rCompare)
341cdf0e10cSrcweir {
342cdf0e10cSrcweir nEnd = pData[nIndex].nEnd;
343cdf0e10cSrcweir break; // while
344cdf0e10cSrcweir }
345cdf0e10cSrcweir else
346cdf0e10cSrcweir {
347cdf0e10cSrcweir if (nIndex > 0)
348cdf0e10cSrcweir {
349cdf0e10cSrcweir --nIndex;
350cdf0e10cSrcweir if (pData[nIndex].nEnd < nStart)
351cdf0e10cSrcweir break; // while
352cdf0e10cSrcweir }
353cdf0e10cSrcweir else
354cdf0e10cSrcweir break; // while
355cdf0e10cSrcweir }
356cdf0e10cSrcweir }
357cdf0e10cSrcweir return nEnd;
358cdf0e10cSrcweir }
359cdf0e10cSrcweir
360cdf0e10cSrcweir
361cdf0e10cSrcweir // === ScSummableCompressedArray =============================================
362cdf0e10cSrcweir
363cdf0e10cSrcweir template< typename A, typename D >
SumValues(A nStart,A nEnd) const364cdf0e10cSrcweir unsigned long ScSummableCompressedArray<A,D>::SumValues( A nStart, A nEnd ) const
365cdf0e10cSrcweir {
366*7ee1d29cSAriel Constenla-Haile size_t nIndex = this->Search( nStart);
367cdf0e10cSrcweir unsigned long nSum = SumValuesContinuation( nStart, nEnd, nIndex);
368cdf0e10cSrcweir if (nEnd > this->nMaxAccess)
369cdf0e10cSrcweir nSum += this->pData[this->nCount-1].aValue * (nEnd - this->nMaxAccess);
370cdf0e10cSrcweir return nSum;
371cdf0e10cSrcweir }
372cdf0e10cSrcweir
373cdf0e10cSrcweir
374cdf0e10cSrcweir template< typename A, typename D >
SumValuesContinuation(A nStart,A nEnd,size_t & nIndex) const375cdf0e10cSrcweir unsigned long ScSummableCompressedArray<A,D>::SumValuesContinuation(
376cdf0e10cSrcweir A nStart, A nEnd, size_t& nIndex ) const
377cdf0e10cSrcweir {
378cdf0e10cSrcweir unsigned long nSum = 0;
379cdf0e10cSrcweir A nS = nStart;
380cdf0e10cSrcweir while (nIndex < this->nCount && nS <= nEnd)
381cdf0e10cSrcweir {
382cdf0e10cSrcweir A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
383cdf0e10cSrcweir // FIXME: test for overflow in a single region?
384cdf0e10cSrcweir unsigned long nNew = (unsigned long) this->pData[nIndex].aValue * (nE - nS + 1);
385cdf0e10cSrcweir nSum += nNew;
386cdf0e10cSrcweir if (nSum < nNew)
387cdf0e10cSrcweir return ::std::numeric_limits<unsigned long>::max();
388cdf0e10cSrcweir nS = nE + 1;
389cdf0e10cSrcweir if (nS <= nEnd)
390cdf0e10cSrcweir ++nIndex;
391cdf0e10cSrcweir }
392cdf0e10cSrcweir return nSum;
393cdf0e10cSrcweir }
394cdf0e10cSrcweir
395cdf0e10cSrcweir
396cdf0e10cSrcweir template< typename A, typename D >
SumScaledValuesContinuation(A nStart,A nEnd,size_t & nIndex,double fScale) const397cdf0e10cSrcweir unsigned long ScSummableCompressedArray<A,D>::SumScaledValuesContinuation(
398cdf0e10cSrcweir A nStart, A nEnd, size_t& nIndex, double fScale ) const
399cdf0e10cSrcweir {
400cdf0e10cSrcweir unsigned long nSum = 0;
401cdf0e10cSrcweir A nS = nStart;
402cdf0e10cSrcweir while (nIndex < this->nCount && nS <= nEnd)
403cdf0e10cSrcweir {
404cdf0e10cSrcweir A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
405cdf0e10cSrcweir unsigned long nScaledVal = (unsigned long) (this->pData[nIndex].aValue * fScale);
406cdf0e10cSrcweir // FIXME: test for overflow in a single region?
407cdf0e10cSrcweir unsigned long nNew = nScaledVal * (nE - nS + 1);
408cdf0e10cSrcweir nSum += nNew;
409cdf0e10cSrcweir if (nSum < nNew)
410cdf0e10cSrcweir return ::std::numeric_limits<unsigned long>::max();
411cdf0e10cSrcweir nS = nE + 1;
412cdf0e10cSrcweir if (nS <= nEnd)
413cdf0e10cSrcweir ++nIndex;
414cdf0e10cSrcweir }
415cdf0e10cSrcweir return nSum;
416cdf0e10cSrcweir }
417cdf0e10cSrcweir
418cdf0e10cSrcweir
419cdf0e10cSrcweir // === ScBitMaskCompressedArray ==============================================
420cdf0e10cSrcweir
421cdf0e10cSrcweir template< typename A, typename D >
AndValue(A nStart,A nEnd,const D & rValueToAnd)422cdf0e10cSrcweir void ScBitMaskCompressedArray<A,D>::AndValue( A nStart, A nEnd,
423cdf0e10cSrcweir const D& rValueToAnd )
424cdf0e10cSrcweir {
425cdf0e10cSrcweir if (nStart > nEnd)
426cdf0e10cSrcweir return;
427cdf0e10cSrcweir
428*7ee1d29cSAriel Constenla-Haile size_t nIndex = this->Search( nStart);
429cdf0e10cSrcweir do
430cdf0e10cSrcweir {
431cdf0e10cSrcweir if ((this->pData[nIndex].aValue & rValueToAnd) != this->pData[nIndex].aValue)
432cdf0e10cSrcweir {
433cdf0e10cSrcweir A nS = ::std::max( (nIndex>0 ? this->pData[nIndex-1].nEnd+1 : 0), nStart);
434cdf0e10cSrcweir A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
435*7ee1d29cSAriel Constenla-Haile this->SetValue( nS, nE, this->pData[nIndex].aValue & rValueToAnd);
436cdf0e10cSrcweir if (nE >= nEnd)
437cdf0e10cSrcweir break; // while
438*7ee1d29cSAriel Constenla-Haile nIndex = this->Search( nE + 1);
439cdf0e10cSrcweir }
440cdf0e10cSrcweir else if (this->pData[nIndex].nEnd >= nEnd)
441cdf0e10cSrcweir break; // while
442cdf0e10cSrcweir else
443cdf0e10cSrcweir ++nIndex;
444cdf0e10cSrcweir } while (nIndex < this->nCount);
445cdf0e10cSrcweir }
446cdf0e10cSrcweir
447cdf0e10cSrcweir
448cdf0e10cSrcweir template< typename A, typename D >
OrValue(A nStart,A nEnd,const D & rValueToOr)449cdf0e10cSrcweir void ScBitMaskCompressedArray<A,D>::OrValue( A nStart, A nEnd,
450cdf0e10cSrcweir const D& rValueToOr )
451cdf0e10cSrcweir {
452cdf0e10cSrcweir if (nStart > nEnd)
453cdf0e10cSrcweir return;
454cdf0e10cSrcweir
455*7ee1d29cSAriel Constenla-Haile size_t nIndex = this->Search( nStart);
456cdf0e10cSrcweir do
457cdf0e10cSrcweir {
458cdf0e10cSrcweir if ((this->pData[nIndex].aValue | rValueToOr) != this->pData[nIndex].aValue)
459cdf0e10cSrcweir {
460cdf0e10cSrcweir A nS = ::std::max( (nIndex>0 ? this->pData[nIndex-1].nEnd+1 : 0), nStart);
461cdf0e10cSrcweir A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
462*7ee1d29cSAriel Constenla-Haile this->SetValue( nS, nE, this->pData[nIndex].aValue | rValueToOr);
463cdf0e10cSrcweir if (nE >= nEnd)
464cdf0e10cSrcweir break; // while
465*7ee1d29cSAriel Constenla-Haile nIndex = this->Search( nE + 1);
466cdf0e10cSrcweir }
467cdf0e10cSrcweir else if (this->pData[nIndex].nEnd >= nEnd)
468cdf0e10cSrcweir break; // while
469cdf0e10cSrcweir else
470cdf0e10cSrcweir ++nIndex;
471cdf0e10cSrcweir } while (nIndex < this->nCount);
472cdf0e10cSrcweir }
473cdf0e10cSrcweir
474cdf0e10cSrcweir
475cdf0e10cSrcweir template< typename A, typename D >
CopyFromAnded(const ScBitMaskCompressedArray<A,D> & rArray,A nStart,A nEnd,const D & rValueToAnd,long nSourceDy)476cdf0e10cSrcweir void ScBitMaskCompressedArray<A,D>::CopyFromAnded(
477cdf0e10cSrcweir const ScBitMaskCompressedArray<A,D>& rArray, A nStart, A nEnd,
478cdf0e10cSrcweir const D& rValueToAnd, long nSourceDy )
479cdf0e10cSrcweir {
480cdf0e10cSrcweir size_t nIndex;
481cdf0e10cSrcweir A nRegionEnd;
482cdf0e10cSrcweir for (A j=nStart; j<=nEnd; ++j)
483cdf0e10cSrcweir {
484cdf0e10cSrcweir const D& rValue = (j==nStart ?
485cdf0e10cSrcweir rArray.GetValue( j+nSourceDy, nIndex, nRegionEnd) :
486cdf0e10cSrcweir rArray.GetNextValue( nIndex, nRegionEnd));
487cdf0e10cSrcweir nRegionEnd -= nSourceDy;
488cdf0e10cSrcweir if (nRegionEnd > nEnd)
489cdf0e10cSrcweir nRegionEnd = nEnd;
490*7ee1d29cSAriel Constenla-Haile this->SetValue( j, nRegionEnd, rValue & rValueToAnd);
491cdf0e10cSrcweir j = nRegionEnd;
492cdf0e10cSrcweir }
493cdf0e10cSrcweir }
494cdf0e10cSrcweir
495cdf0e10cSrcweir
496cdf0e10cSrcweir template< typename A, typename D >
CopyFromOred(const ScBitMaskCompressedArray<A,D> & rArray,A nStart,A nEnd,const D & rValueToOr,long nSourceDy)497cdf0e10cSrcweir void ScBitMaskCompressedArray<A,D>::CopyFromOred(
498cdf0e10cSrcweir const ScBitMaskCompressedArray<A,D>& rArray, A nStart, A nEnd,
499cdf0e10cSrcweir const D& rValueToOr, long nSourceDy )
500cdf0e10cSrcweir {
501cdf0e10cSrcweir size_t nIndex;
502cdf0e10cSrcweir A nRegionEnd;
503cdf0e10cSrcweir for (A j=nStart; j<=nEnd; ++j)
504cdf0e10cSrcweir {
505cdf0e10cSrcweir const D& rValue = (j==nStart ?
506cdf0e10cSrcweir rArray.GetValue( j+nSourceDy, nIndex, nRegionEnd) :
507cdf0e10cSrcweir rArray.GetNextValue( nIndex, nRegionEnd));
508cdf0e10cSrcweir nRegionEnd -= nSourceDy;
509cdf0e10cSrcweir if (nRegionEnd > nEnd)
510cdf0e10cSrcweir nRegionEnd = nEnd;
511*7ee1d29cSAriel Constenla-Haile this->SetValue( j, nRegionEnd, rValue | rValueToOr);
512cdf0e10cSrcweir j = nRegionEnd;
513cdf0e10cSrcweir }
514cdf0e10cSrcweir }
515cdf0e10cSrcweir
516cdf0e10cSrcweir
517cdf0e10cSrcweir template< typename A, typename D >
GetBitStateStart(A nEnd,const D & rBitMask,const D & rMaskedCompare) const518cdf0e10cSrcweir A ScBitMaskCompressedArray<A,D>::GetBitStateStart( A nEnd,
519cdf0e10cSrcweir const D& rBitMask, const D& rMaskedCompare ) const
520cdf0e10cSrcweir {
521cdf0e10cSrcweir A nStart = ::std::numeric_limits<A>::max();
522*7ee1d29cSAriel Constenla-Haile size_t nIndex = this->Search( nEnd);
523cdf0e10cSrcweir while ((this->pData[nIndex].aValue & rBitMask) == rMaskedCompare)
524cdf0e10cSrcweir {
525cdf0e10cSrcweir if (nIndex > 0)
526cdf0e10cSrcweir {
527cdf0e10cSrcweir --nIndex;
528cdf0e10cSrcweir nStart = this->pData[nIndex].nEnd + 1;
529cdf0e10cSrcweir }
530cdf0e10cSrcweir else
531cdf0e10cSrcweir {
532cdf0e10cSrcweir nStart = 0;
533cdf0e10cSrcweir break; // while
534cdf0e10cSrcweir }
535cdf0e10cSrcweir }
536cdf0e10cSrcweir return nStart;
537cdf0e10cSrcweir }
538cdf0e10cSrcweir
539cdf0e10cSrcweir
540cdf0e10cSrcweir template< typename A, typename D >
GetBitStateEnd(A nStart,const D & rBitMask,const D & rMaskedCompare) const541cdf0e10cSrcweir A ScBitMaskCompressedArray<A,D>::GetBitStateEnd( A nStart,
542cdf0e10cSrcweir const D& rBitMask, const D& rMaskedCompare ) const
543cdf0e10cSrcweir {
544cdf0e10cSrcweir A nEnd = ::std::numeric_limits<A>::max();
545*7ee1d29cSAriel Constenla-Haile size_t nIndex = this->Search( nStart);
546cdf0e10cSrcweir while (nIndex < this->nCount && (this->pData[nIndex].aValue & rBitMask) ==
547cdf0e10cSrcweir rMaskedCompare)
548cdf0e10cSrcweir {
549cdf0e10cSrcweir nEnd = this->pData[nIndex].nEnd;
550cdf0e10cSrcweir ++nIndex;
551cdf0e10cSrcweir }
552cdf0e10cSrcweir return nEnd;
553cdf0e10cSrcweir }
554cdf0e10cSrcweir
555cdf0e10cSrcweir
556cdf0e10cSrcweir template< typename A, typename D >
GetFirstForCondition(A nStart,A nEnd,const D & rBitMask,const D & rMaskedCompare) const557cdf0e10cSrcweir A ScBitMaskCompressedArray<A,D>::GetFirstForCondition( A nStart, A nEnd,
558cdf0e10cSrcweir const D& rBitMask, const D& rMaskedCompare ) const
559cdf0e10cSrcweir {
560*7ee1d29cSAriel Constenla-Haile size_t nIndex = this->Search( nStart);
561cdf0e10cSrcweir do
562cdf0e10cSrcweir {
563cdf0e10cSrcweir if ((this->pData[nIndex].aValue & rBitMask) == rMaskedCompare)
564cdf0e10cSrcweir {
565cdf0e10cSrcweir A nFound = nIndex > 0 ? this->pData[nIndex-1].nEnd + 1 : 0;
566cdf0e10cSrcweir return ::std::max( nFound, nStart);
567cdf0e10cSrcweir }
568cdf0e10cSrcweir if (this->pData[nIndex].nEnd >= nEnd)
569cdf0e10cSrcweir break; // while
570cdf0e10cSrcweir ++nIndex;
571cdf0e10cSrcweir } while (nIndex < this->nCount);
572cdf0e10cSrcweir return ::std::numeric_limits<A>::max();
573cdf0e10cSrcweir }
574cdf0e10cSrcweir
575cdf0e10cSrcweir
576cdf0e10cSrcweir template< typename A, typename D >
GetLastForCondition(A nStart,A nEnd,const D & rBitMask,const D & rMaskedCompare) const577cdf0e10cSrcweir A ScBitMaskCompressedArray<A,D>::GetLastForCondition( A nStart, A nEnd,
578cdf0e10cSrcweir const D& rBitMask, const D& rMaskedCompare ) const
579cdf0e10cSrcweir {
580*7ee1d29cSAriel Constenla-Haile size_t nIndex = this->Search( nEnd);
581cdf0e10cSrcweir while (1)
582cdf0e10cSrcweir {
583cdf0e10cSrcweir if ((this->pData[nIndex].aValue & rBitMask) == rMaskedCompare)
584cdf0e10cSrcweir return ::std::min( this->pData[nIndex].nEnd, nEnd);
585cdf0e10cSrcweir
586cdf0e10cSrcweir if (nIndex > 0)
587cdf0e10cSrcweir {
588cdf0e10cSrcweir --nIndex;
589cdf0e10cSrcweir if (this->pData[nIndex].nEnd < nStart)
590cdf0e10cSrcweir break; // while
591cdf0e10cSrcweir }
592cdf0e10cSrcweir else
593cdf0e10cSrcweir break; // while
594cdf0e10cSrcweir }
595cdf0e10cSrcweir return ::std::numeric_limits<A>::max();
596cdf0e10cSrcweir }
597cdf0e10cSrcweir
598cdf0e10cSrcweir
599cdf0e10cSrcweir template< typename A, typename D >
CountForCondition(A nStart,A nEnd,const D & rBitMask,const D & rMaskedCompare) const600cdf0e10cSrcweir A ScBitMaskCompressedArray<A,D>::CountForCondition( A nStart, A nEnd,
601cdf0e10cSrcweir const D& rBitMask, const D& rMaskedCompare ) const
602cdf0e10cSrcweir {
603cdf0e10cSrcweir A nRet = 0;
604*7ee1d29cSAriel Constenla-Haile size_t nIndex = this->Search( nStart);
605cdf0e10cSrcweir do
606cdf0e10cSrcweir {
607cdf0e10cSrcweir if ((this->pData[nIndex].aValue & rBitMask) == rMaskedCompare)
608cdf0e10cSrcweir {
609cdf0e10cSrcweir A nS = ::std::max( (nIndex>0 ? this->pData[nIndex-1].nEnd+1 : 0), nStart);
610cdf0e10cSrcweir A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
611cdf0e10cSrcweir nRet += nE - nS + 1;
612cdf0e10cSrcweir }
613cdf0e10cSrcweir if (this->pData[nIndex].nEnd >= nEnd)
614cdf0e10cSrcweir break; // while
615cdf0e10cSrcweir ++nIndex;
616cdf0e10cSrcweir } while (nIndex < this->nCount);
617cdf0e10cSrcweir return nRet;
618cdf0e10cSrcweir }
619cdf0e10cSrcweir
620cdf0e10cSrcweir
621cdf0e10cSrcweir template< typename A, typename D >
FillArrayForCondition(A nStart,A nEnd,const D & rBitMask,const D & rMaskedCompare,A * pArray,size_t nArraySize) const622cdf0e10cSrcweir size_t ScBitMaskCompressedArray<A,D>::FillArrayForCondition( A nStart, A nEnd,
623cdf0e10cSrcweir const D& rBitMask, const D& rMaskedCompare,
624cdf0e10cSrcweir A * pArray, size_t nArraySize ) const
625cdf0e10cSrcweir {
626cdf0e10cSrcweir size_t nUsed = 0;
627*7ee1d29cSAriel Constenla-Haile size_t nIndex = this->Search( nStart);
628cdf0e10cSrcweir while (nIndex < this->nCount && nUsed < nArraySize)
629cdf0e10cSrcweir {
630cdf0e10cSrcweir if ((this->pData[nIndex].aValue & rBitMask) == rMaskedCompare)
631cdf0e10cSrcweir {
632cdf0e10cSrcweir A nS = ::std::max( (nIndex>0 ? this->pData[nIndex-1].nEnd+1 : 0), nStart);
633cdf0e10cSrcweir A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
634cdf0e10cSrcweir while (nS <= nE && nUsed < nArraySize)
635cdf0e10cSrcweir pArray[nUsed++] = nS++;
636cdf0e10cSrcweir }
637cdf0e10cSrcweir if (this->pData[nIndex].nEnd >= nEnd)
638cdf0e10cSrcweir break; // while
639cdf0e10cSrcweir ++nIndex;
640cdf0e10cSrcweir }
641cdf0e10cSrcweir return nUsed;
642cdf0e10cSrcweir }
643cdf0e10cSrcweir
644cdf0e10cSrcweir
645cdf0e10cSrcweir template< typename A, typename D >
HasCondition(A nStart,A nEnd,const D & rBitMask,const D & rMaskedCompare) const646cdf0e10cSrcweir bool ScBitMaskCompressedArray<A,D>::HasCondition( A nStart, A nEnd,
647cdf0e10cSrcweir const D& rBitMask, const D& rMaskedCompare ) const
648cdf0e10cSrcweir {
649*7ee1d29cSAriel Constenla-Haile size_t nIndex = this->Search( nStart);
650cdf0e10cSrcweir do
651cdf0e10cSrcweir {
652cdf0e10cSrcweir if ((this->pData[nIndex].aValue & rBitMask) == rMaskedCompare)
653cdf0e10cSrcweir return true;
654cdf0e10cSrcweir if (this->pData[nIndex].nEnd >= nEnd)
655cdf0e10cSrcweir break; // while
656cdf0e10cSrcweir ++nIndex;
657cdf0e10cSrcweir } while (nIndex < this->nCount);
658cdf0e10cSrcweir return false;
659cdf0e10cSrcweir }
660cdf0e10cSrcweir
661cdf0e10cSrcweir
662cdf0e10cSrcweir template< typename A, typename D >
CountForAnyBitCondition(A nStart,A nEnd,const D & rBitMask) const663cdf0e10cSrcweir A ScBitMaskCompressedArray<A,D>::CountForAnyBitCondition( A nStart, A nEnd,
664cdf0e10cSrcweir const D& rBitMask ) const
665cdf0e10cSrcweir {
666cdf0e10cSrcweir A nRet = 0;
667*7ee1d29cSAriel Constenla-Haile size_t nIndex = this->Search( nStart);
668cdf0e10cSrcweir do
669cdf0e10cSrcweir {
670cdf0e10cSrcweir if ((this->pData[nIndex].aValue & rBitMask) != 0)
671cdf0e10cSrcweir {
672cdf0e10cSrcweir A nS = ::std::max( (nIndex>0 ? this->pData[nIndex-1].nEnd+1 : 0), nStart);
673cdf0e10cSrcweir A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
674cdf0e10cSrcweir nRet += nE - nS + 1;
675cdf0e10cSrcweir }
676cdf0e10cSrcweir if (this->pData[nIndex].nEnd >= nEnd)
677cdf0e10cSrcweir break; // while
678cdf0e10cSrcweir ++nIndex;
679cdf0e10cSrcweir } while (nIndex < this->nCount);
680cdf0e10cSrcweir return nRet;
681cdf0e10cSrcweir }
682cdf0e10cSrcweir
683cdf0e10cSrcweir
684cdf0e10cSrcweir template< typename A, typename D >
GetLastAnyBitAccess(A nStart,const D & rBitMask) const685cdf0e10cSrcweir A ScBitMaskCompressedArray<A,D>::GetLastAnyBitAccess( A nStart,
686cdf0e10cSrcweir const D& rBitMask ) const
687cdf0e10cSrcweir {
688cdf0e10cSrcweir A nEnd = ::std::numeric_limits<A>::max();
689cdf0e10cSrcweir size_t nIndex = this->nCount-1;
690cdf0e10cSrcweir while (1)
691cdf0e10cSrcweir {
692cdf0e10cSrcweir if ((this->pData[nIndex].aValue & rBitMask) != 0)
693cdf0e10cSrcweir {
694cdf0e10cSrcweir nEnd = this->pData[nIndex].nEnd;
695cdf0e10cSrcweir break; // while
696cdf0e10cSrcweir }
697cdf0e10cSrcweir else
698cdf0e10cSrcweir {
699cdf0e10cSrcweir if (nIndex > 0)
700cdf0e10cSrcweir {
701cdf0e10cSrcweir --nIndex;
702cdf0e10cSrcweir if (this->pData[nIndex].nEnd < nStart)
703cdf0e10cSrcweir break; // while
704cdf0e10cSrcweir }
705cdf0e10cSrcweir else
706cdf0e10cSrcweir break; // while
707cdf0e10cSrcweir }
708cdf0e10cSrcweir }
709cdf0e10cSrcweir return nEnd;
710cdf0e10cSrcweir }
711cdf0e10cSrcweir
712cdf0e10cSrcweir
713cdf0e10cSrcweir template< typename A, typename D >
714cdf0e10cSrcweir template< typename S >
SumCoupledArrayForCondition(A nStart,A nEnd,const D & rBitMask,const D & rMaskedCompare,const ScSummableCompressedArray<A,S> & rArray) const715cdf0e10cSrcweir unsigned long ScBitMaskCompressedArray<A,D>::SumCoupledArrayForCondition(
716cdf0e10cSrcweir A nStart, A nEnd, const D& rBitMask, const D& rMaskedCompare,
717cdf0e10cSrcweir const ScSummableCompressedArray<A,S>& rArray ) const
718cdf0e10cSrcweir {
719cdf0e10cSrcweir unsigned long nSum = 0;
720cdf0e10cSrcweir A nS = nStart;
721*7ee1d29cSAriel Constenla-Haile size_t nIndex1 = this->Search( nStart);
722cdf0e10cSrcweir size_t nIndex2 = rArray.Search( nStart);
723cdf0e10cSrcweir do
724cdf0e10cSrcweir {
725cdf0e10cSrcweir if ((this->pData[nIndex1].aValue & rBitMask) == rMaskedCompare)
726cdf0e10cSrcweir {
727cdf0e10cSrcweir while (nIndex2 < rArray.GetEntryCount() &&
728cdf0e10cSrcweir rArray.GetDataEntry(nIndex2).nEnd < nS)
729cdf0e10cSrcweir ++nIndex2;
730cdf0e10cSrcweir unsigned long nNew = rArray.SumValuesContinuation( nS,
731cdf0e10cSrcweir ::std::min( this->pData[nIndex1].nEnd, nEnd), nIndex2);
732cdf0e10cSrcweir nSum += nNew;
733cdf0e10cSrcweir if (nSum < nNew)
734cdf0e10cSrcweir return ::std::numeric_limits<unsigned long>::max();
735cdf0e10cSrcweir }
736cdf0e10cSrcweir nS = this->pData[nIndex1].nEnd + 1;
737cdf0e10cSrcweir ++nIndex1;
738cdf0e10cSrcweir } while (nIndex1 < this->nCount && nS <= nEnd);
739cdf0e10cSrcweir if (nEnd > this->nMaxAccess &&
740cdf0e10cSrcweir (this->pData[this->GetEntryCount()-1].aValue & rBitMask) == rMaskedCompare)
741cdf0e10cSrcweir nSum += rArray.GetDataEntry(rArray.GetEntryCount()-1).aValue * (nEnd -
742cdf0e10cSrcweir this->nMaxAccess);
743cdf0e10cSrcweir return nSum;
744cdf0e10cSrcweir }
745cdf0e10cSrcweir
746cdf0e10cSrcweir
747cdf0e10cSrcweir template< typename A, typename D >
748cdf0e10cSrcweir template< typename S >
SumScaledCoupledArrayForCondition(A nStart,A nEnd,const D & rBitMask,const D & rMaskedCompare,const ScSummableCompressedArray<A,S> & rArray,double fScale) const749cdf0e10cSrcweir unsigned long ScBitMaskCompressedArray<A,D>::SumScaledCoupledArrayForCondition(
750cdf0e10cSrcweir A nStart, A nEnd, const D& rBitMask, const D& rMaskedCompare,
751cdf0e10cSrcweir const ScSummableCompressedArray<A,S>& rArray, double fScale ) const
752cdf0e10cSrcweir {
753cdf0e10cSrcweir unsigned long nSum = 0;
754cdf0e10cSrcweir A nS = nStart;
755*7ee1d29cSAriel Constenla-Haile size_t nIndex1 = this->Search( nStart);
756cdf0e10cSrcweir size_t nIndex2 = rArray.Search( nStart);
757cdf0e10cSrcweir do
758cdf0e10cSrcweir {
759cdf0e10cSrcweir if ((this->pData[nIndex1].aValue & rBitMask) == rMaskedCompare)
760cdf0e10cSrcweir {
761cdf0e10cSrcweir while (nIndex2 < rArray.GetEntryCount() &&
762cdf0e10cSrcweir rArray.GetDataEntry(nIndex2).nEnd < nS)
763cdf0e10cSrcweir ++nIndex2;
764cdf0e10cSrcweir unsigned long nNew = rArray.SumScaledValuesContinuation( nS,
765cdf0e10cSrcweir ::std::min( this->pData[nIndex1].nEnd, nEnd), nIndex2, fScale);
766cdf0e10cSrcweir nSum += nNew;
767cdf0e10cSrcweir if (nSum < nNew)
768cdf0e10cSrcweir return ::std::numeric_limits<unsigned long>::max();
769cdf0e10cSrcweir }
770cdf0e10cSrcweir nS = this->pData[nIndex1].nEnd + 1;
771cdf0e10cSrcweir ++nIndex1;
772cdf0e10cSrcweir } while (nIndex1 < this->nCount && nS <= nEnd);
773cdf0e10cSrcweir if (nEnd > this->nMaxAccess &&
774cdf0e10cSrcweir (this->pData[this->GetEntryCount()-1].aValue & rBitMask) == rMaskedCompare)
775cdf0e10cSrcweir nSum += (unsigned long)
776cdf0e10cSrcweir (rArray.GetDataEntry(rArray.GetEntryCount()-1).aValue * fScale) *
777cdf0e10cSrcweir (nEnd - this->nMaxAccess);
778cdf0e10cSrcweir return nSum;
779cdf0e10cSrcweir }
780cdf0e10cSrcweir
781cdf0e10cSrcweir
782cdf0e10cSrcweir // === ScCompressedArrayIterator =============================================
783cdf0e10cSrcweir
784cdf0e10cSrcweir template< typename A, typename D >
785cdf0e10cSrcweir template< typename X >
Follow(const ScCompressedArrayIterator<A,X> & rIter)786cdf0e10cSrcweir void ScCompressedArrayIterator<A,D>::Follow(
787cdf0e10cSrcweir const ScCompressedArrayIterator<A,X>& rIter )
788cdf0e10cSrcweir {
789cdf0e10cSrcweir nCurrent = rIter.GetPos();
790cdf0e10cSrcweir if (GetRangeStart() <= nCurrent && nCurrent <= GetRangeEnd())
791cdf0e10cSrcweir ; // nothing
792cdf0e10cSrcweir else if (nCurrent > GetRangeEnd())
793cdf0e10cSrcweir {
794cdf0e10cSrcweir A nPos = nCurrent; // nCurrent gets changed in NextRange()
795cdf0e10cSrcweir bool bAdv;
796cdf0e10cSrcweir do
797cdf0e10cSrcweir {
798cdf0e10cSrcweir bAdv = NextRange();
799cdf0e10cSrcweir } while (bAdv && GetRangeEnd() < nPos);
800cdf0e10cSrcweir nCurrent = nPos;
801cdf0e10cSrcweir }
802cdf0e10cSrcweir else
803cdf0e10cSrcweir nIndex = rArray.Search( nCurrent);
804cdf0e10cSrcweir }
805cdf0e10cSrcweir
806cdf0e10cSrcweir
807cdf0e10cSrcweir // === ScCoupledCompressedArrayIterator ======================================
808cdf0e10cSrcweir
809cdf0e10cSrcweir template< typename A, typename D, typename S >
ScCoupledCompressedArrayIterator(const ScBitMaskCompressedArray<A,D> & rArray1,A nStart,A nEnd,const D & rBitMaskP,const D & rMaskedCompareP,const ScCompressedArray<A,S> & rArray2)810cdf0e10cSrcweir ScCoupledCompressedArrayIterator<A,D,S>::ScCoupledCompressedArrayIterator(
811cdf0e10cSrcweir const ScBitMaskCompressedArray<A,D> & rArray1, A nStart, A nEnd,
812cdf0e10cSrcweir const D& rBitMaskP, const D& rMaskedCompareP,
813cdf0e10cSrcweir const ScCompressedArray<A,S> & rArray2 )
814cdf0e10cSrcweir : aIter1( rArray1, nStart, nEnd )
815cdf0e10cSrcweir , aIter2( rArray2, nStart, nEnd )
816cdf0e10cSrcweir , rBitMask( rBitMaskP )
817cdf0e10cSrcweir , rMaskedCompare( rMaskedCompareP )
818cdf0e10cSrcweir {
819cdf0e10cSrcweir InitLimits();
820cdf0e10cSrcweir }
821cdf0e10cSrcweir
822cdf0e10cSrcweir
823cdf0e10cSrcweir template< typename A, typename D, typename S >
InitLimits()824cdf0e10cSrcweir void ScCoupledCompressedArrayIterator<A,D,S>::InitLimits()
825cdf0e10cSrcweir {
826cdf0e10cSrcweir bool bFound = true;
827cdf0e10cSrcweir bool bMoved = false;
828cdf0e10cSrcweir while (bFound && ((*aIter1 & rBitMask) != rMaskedCompare))
829cdf0e10cSrcweir {
830cdf0e10cSrcweir bFound = aIter1.NextRange();
831cdf0e10cSrcweir bMoved = true;
832cdf0e10cSrcweir }
833cdf0e10cSrcweir if (bMoved && bFound)
834cdf0e10cSrcweir aIter2.Follow( aIter1);
835cdf0e10cSrcweir }
836cdf0e10cSrcweir
837cdf0e10cSrcweir
838cdf0e10cSrcweir template< typename A, typename D, typename S >
NewLimits(A nStart,A nEnd)839cdf0e10cSrcweir void ScCoupledCompressedArrayIterator<A,D,S>::NewLimits( A nStart, A nEnd )
840cdf0e10cSrcweir {
841cdf0e10cSrcweir aIter1.NewLimits( nStart, nEnd);
842cdf0e10cSrcweir aIter2.NewLimits( nStart, nEnd);
843cdf0e10cSrcweir InitLimits();
844cdf0e10cSrcweir }
845cdf0e10cSrcweir
846cdf0e10cSrcweir
847cdf0e10cSrcweir template< typename A, typename D, typename S >
NextRange()848cdf0e10cSrcweir bool ScCoupledCompressedArrayIterator<A,D,S>::NextRange()
849cdf0e10cSrcweir {
850cdf0e10cSrcweir bool bAdv;
851cdf0e10cSrcweir if (aIter1.GetRangeEnd() <= aIter2.GetRangeEnd())
852cdf0e10cSrcweir {
853cdf0e10cSrcweir // Advance bit mask array until condition is met, coupled array
854cdf0e10cSrcweir // follows.
855cdf0e10cSrcweir do
856cdf0e10cSrcweir {
857cdf0e10cSrcweir bAdv = aIter1.NextRange();
858cdf0e10cSrcweir } while (bAdv && ((*aIter1 & rBitMask) != rMaskedCompare));
859cdf0e10cSrcweir if (bAdv)
860cdf0e10cSrcweir aIter2.Follow( aIter1);
861cdf0e10cSrcweir }
862cdf0e10cSrcweir else
863cdf0e10cSrcweir {
864cdf0e10cSrcweir // Make coupled array catch up with bit mask array.
865cdf0e10cSrcweir do
866cdf0e10cSrcweir {
867cdf0e10cSrcweir bAdv = aIter2.NextRange();
868cdf0e10cSrcweir } while (bAdv && aIter2.GetRangeEnd() < aIter1.GetRangeStart());
869cdf0e10cSrcweir if (bAdv)
870cdf0e10cSrcweir aIter1.Follow( aIter2); // synchronize aIter1.nCurrent
871cdf0e10cSrcweir }
872cdf0e10cSrcweir return operator bool();
873cdf0e10cSrcweir }
874cdf0e10cSrcweir
875cdf0e10cSrcweir
876cdf0e10cSrcweir template< typename A, typename D, typename S >
Resync(A nPos)877cdf0e10cSrcweir void ScCoupledCompressedArrayIterator<A,D,S>::Resync( A nPos )
878cdf0e10cSrcweir {
879cdf0e10cSrcweir aIter1.Resync( nPos);
880cdf0e10cSrcweir aIter2.Resync( nPos);
881cdf0e10cSrcweir InitLimits();
882cdf0e10cSrcweir }
883cdf0e10cSrcweir
884cdf0e10cSrcweir
885cdf0e10cSrcweir // === Force instantiation of specializations ================================
886cdf0e10cSrcweir
887cdf0e10cSrcweir template class ScCompressedArray< SCROW, sal_uInt16>; // heights, base class
888cdf0e10cSrcweir template class ScSummableCompressedArray< SCROW, sal_uInt16>; // heights
889cdf0e10cSrcweir template class ScCompressedArray< SCROW, sal_uInt8>; // flags, base class
890cdf0e10cSrcweir template class ScBitMaskCompressedArray< SCROW, sal_uInt8>; // flags
891cdf0e10cSrcweir template unsigned long ScBitMaskCompressedArray< SCROW,
892cdf0e10cSrcweir sal_uInt8>::SumCoupledArrayForCondition( SCROW, SCROW, const sal_uInt8&, const sal_uInt8&,
893cdf0e10cSrcweir const ScSummableCompressedArray< SCROW, sal_uInt16>&) const;
894cdf0e10cSrcweir template unsigned long ScBitMaskCompressedArray< SCROW,
895cdf0e10cSrcweir sal_uInt8>::SumScaledCoupledArrayForCondition( SCROW, SCROW, const sal_uInt8&,
896cdf0e10cSrcweir const sal_uInt8&, const ScSummableCompressedArray< SCROW, sal_uInt16>&,
897cdf0e10cSrcweir double) const;
898cdf0e10cSrcweir template void ScCompressedArrayIterator< SCROW, sal_uInt16>::Follow(
899cdf0e10cSrcweir const ScCompressedArrayIterator< SCROW, sal_uInt8>&);
900cdf0e10cSrcweir template class ScCoupledCompressedArrayIterator< SCROW, sal_uInt8, sal_uInt16>;
901cdf0e10cSrcweir
902cdf0e10cSrcweir // === EOF ===================================================================
903