diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-06-27 15:06:22 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-06-28 08:50:35 +0200 |
commit | 1eee0abd459a508a6dcf9e71cbf2c1be3725faa7 (patch) | |
tree | 9d9775249923ea166db8c997e506aebff4ff4ae2 /sw | |
parent | 7b850c15b15be10ed3b52822f63b02d8787bcb2f (diff) |
use std::vector in BigPtrArray
Change-Id: Ibf63213eb44ef2bb51042607cbdedcb66181b51a
Reviewed-on: https://gerrit.libreoffice.org/39302
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/bparr.hxx | 7 | ||||
-rw-r--r-- | sw/source/core/bastyp/bparr.cxx | 113 | ||||
-rw-r--r-- | sw/source/core/docnode/nodes.cxx | 2 |
3 files changed, 45 insertions, 77 deletions
diff --git a/sw/inc/bparr.hxx b/sw/inc/bparr.hxx index c51e959ada1d..90f00231fa3d 100644 --- a/sw/inc/bparr.hxx +++ b/sw/inc/bparr.hxx @@ -25,6 +25,7 @@ #include <tools/solar.h> #include <swdllapi.h> #include <array> +#include <vector> struct BlockInfo; class BigPtrArray; @@ -66,16 +67,14 @@ struct BlockInfo final class SW_DLLPUBLIC BigPtrArray { protected: - BlockInfo** m_ppInf; ///< block info + std::vector<BlockInfo*> + m_vpInf; ///< block info sal_uLong m_nSize; ///< number of elements - sal_uInt16 m_nMaxBlock; ///< current max. number of blocks - sal_uInt16 m_nBlock; ///< number of blocks mutable sal_uInt16 m_nCur; ///< last used block sal_uInt16 Index2Block( sal_uLong ) const; ///< block search BlockInfo* InsBlock( sal_uInt16 ); ///< insert block - void BlockDel( sal_uInt16 ); ///< some blocks were deleted void UpdIndex( sal_uInt16 ); ///< recalculate indices // fill all blocks diff --git a/sw/source/core/bastyp/bparr.cxx b/sw/source/core/bastyp/bparr.cxx index c5331bcf11d6..2cb854a402b0 100644 --- a/sw/source/core/bastyp/bparr.cxx +++ b/sw/source/core/bastyp/bparr.cxx @@ -21,6 +21,7 @@ #include <limits.h> #include <string.h> +#include <algorithm> /** Resize block management by this constant. As a result there are approx. 20 * MAXENTRY == 20000 entries available */ @@ -47,23 +48,21 @@ void CheckIdx( BlockInfo** ppInf, sal_uInt16 nBlock, sal_uLong nSize, sal_uInt16 BigPtrArray::BigPtrArray() { - m_nBlock = m_nCur = 0; + m_nCur = 0; m_nSize = 0; - m_nMaxBlock = nBlockGrowSize; - m_ppInf = new BlockInfo* [ m_nMaxBlock ]; + m_vpInf.reserve( nBlockGrowSize ); } BigPtrArray::~BigPtrArray() { - if( m_nBlock ) + if( m_vpInf.size() ) { - BlockInfo** pp = m_ppInf; - for( sal_uInt16 n = 0; n < m_nBlock; ++n, ++pp ) + BlockInfo** pp = m_vpInf.data(); + for( sal_uInt16 n = 0; n < sal_uInt16(m_vpInf.size()); ++n, ++pp ) { delete *pp; } } - delete[] m_ppInf; } // Also moving is done simply here. Optimization is useless because of the @@ -73,7 +72,7 @@ void BigPtrArray::Move( sal_uLong from, sal_uLong to ) if (from != to) { sal_uInt16 cur = Index2Block( from ); - BlockInfo* p = m_ppInf[ cur ]; + BlockInfo* p = m_vpInf[ cur ]; BigPtrEntry* pElem = p->mvData[ from - p->nStart ]; Insert( pElem, to ); // insert first, then delete! Remove( ( to < from ) ? ( from + 1 ) : from ); @@ -84,7 +83,7 @@ BigPtrEntry* BigPtrArray::operator[]( sal_uLong idx ) const { assert(idx < m_nSize); // operator[]: Index out of bounds m_nCur = Index2Block( idx ); - BlockInfo* p = m_ppInf[ m_nCur ]; + BlockInfo* p = m_vpInf[ m_nCur ]; return p->mvData[ idx - p->nStart ]; } @@ -92,7 +91,7 @@ BigPtrEntry* BigPtrArray::operator[]( sal_uLong idx ) const sal_uInt16 BigPtrArray::Index2Block( sal_uLong pos ) const { // last used block? - BlockInfo* p = m_ppInf[ m_nCur ]; + BlockInfo* p = m_vpInf[ m_nCur ]; if( p->nStart <= pos && p->nEnd >= pos ) return m_nCur; // Index = 0? @@ -100,28 +99,28 @@ sal_uInt16 BigPtrArray::Index2Block( sal_uLong pos ) const return 0; // following one? - if( m_nCur < ( m_nBlock - 1 ) ) + if( m_nCur < ( m_vpInf.size() - 1 ) ) { - p = m_ppInf[ m_nCur+1 ]; + p = m_vpInf[ m_nCur+1 ]; if( p->nStart <= pos && p->nEnd >= pos ) return m_nCur+1; } // previous one? else if( pos < p->nStart && m_nCur > 0 ) { - p = m_ppInf[ m_nCur-1 ]; + p = m_vpInf[ m_nCur-1 ]; if( p->nStart <= pos && p->nEnd >= pos ) return m_nCur-1; } // binary search: always successful - sal_uInt16 lower = 0, upper = m_nBlock - 1; + sal_uInt16 lower = 0, upper = m_vpInf.size() - 1; sal_uInt16 cur = 0; for(;;) { sal_uInt16 n = lower + ( upper - lower ) / 2; cur = ( n == cur ) ? n+1 : n; - p = m_ppInf[ cur ]; + p = m_vpInf[ cur ]; if( p->nStart <= pos && p->nEnd >= pos ) return cur; @@ -138,9 +137,9 @@ sal_uInt16 BigPtrArray::Index2Block( sal_uLong pos ) const */ void BigPtrArray::UpdIndex( sal_uInt16 pos ) { - BlockInfo** pp = m_ppInf + pos; + BlockInfo** pp = m_vpInf.data() + pos; sal_uLong idx = (*pp)->nEnd + 1; - while( ++pos < m_nBlock ) + while( ++pos < m_vpInf.size() ) { BlockInfo* p = *++pp; p->nStart = idx; @@ -157,26 +156,11 @@ void BigPtrArray::UpdIndex( sal_uInt16 pos ) */ BlockInfo* BigPtrArray::InsBlock( sal_uInt16 pos ) { - if( m_nBlock == m_nMaxBlock ) - { - // than extend the array first - BlockInfo** ppNew = new BlockInfo* [ m_nMaxBlock + nBlockGrowSize ]; - memcpy( ppNew, m_ppInf, m_nMaxBlock * sizeof( BlockInfo* )); - delete[] m_ppInf; - m_nMaxBlock += nBlockGrowSize; - m_ppInf = ppNew; - } - if( pos != m_nBlock ) - { - memmove( m_ppInf + pos+1, m_ppInf + pos, - ( m_nBlock - pos ) * sizeof( BlockInfo* )); - } - ++m_nBlock; BlockInfo* p = new BlockInfo(this); - m_ppInf[ pos ] = p; + m_vpInf.insert( m_vpInf.begin() + pos, p ); if( pos ) - p->nStart = p->nEnd = m_ppInf[ pos-1 ]->nEnd + 1; + p->nStart = p->nEnd = m_vpInf[ pos-1 ]->nEnd + 1; else p->nStart = p->nEnd = 0; @@ -185,21 +169,6 @@ BlockInfo* BigPtrArray::InsBlock( sal_uInt16 pos ) return p; } -void BigPtrArray::BlockDel( sal_uInt16 nDel ) -{ - m_nBlock = m_nBlock - nDel; - if( m_nMaxBlock - m_nBlock > nBlockGrowSize ) - { - // than shrink array - nDel = (( m_nBlock / nBlockGrowSize ) + 1 ) * nBlockGrowSize; - BlockInfo** ppNew = new BlockInfo* [ nDel ]; - memcpy( ppNew, m_ppInf, m_nBlock * sizeof( BlockInfo* )); - delete[] m_ppInf; - m_ppInf = ppNew; - m_nMaxBlock = nDel; - } -} - void BigPtrArray::Insert( BigPtrEntry* pElem, sal_uLong pos ) { CHECKIDX( ppInf, nBlock, nSize, nCur ); @@ -214,8 +183,8 @@ void BigPtrArray::Insert( BigPtrEntry* pElem, sal_uLong pos ) else if( pos == m_nSize ) { // special case: insert at end - cur = m_nBlock - 1; - p = m_ppInf[ cur ]; + cur = m_vpInf.size() - 1; + p = m_vpInf[ cur ]; if( p->nElem == MAXENTRY ) // the last block is full, create a new one p = InsBlock( ++cur ); @@ -224,16 +193,16 @@ void BigPtrArray::Insert( BigPtrEntry* pElem, sal_uLong pos ) { // standard case: cur = Index2Block( pos ); - p = m_ppInf[ cur ]; + p = m_vpInf[ cur ]; } if( p->nElem == MAXENTRY ) { // does the last entry fit into the next block? BlockInfo* q; - if( cur < ( m_nBlock - 1 ) && m_ppInf[ cur+1 ]->nElem < MAXENTRY ) + if( cur < ( m_vpInf.size() - 1 ) && m_vpInf[ cur+1 ]->nElem < MAXENTRY ) { - q = m_ppInf[ cur+1 ]; + q = m_vpInf[ cur+1 ]; if( q->nElem ) { int nCount = q->nElem; @@ -250,7 +219,7 @@ void BigPtrArray::Insert( BigPtrEntry* pElem, sal_uLong pos ) // If it does not fit, then insert a new block. But if there is more // than 50% space in the array then compress first. if( /*nBlock == nMaxBlock &&*/ - m_nBlock > ( m_nSize / ( MAXENTRY / 2 ) ) && + m_vpInf.size() > ( m_nSize / ( MAXENTRY / 2 ) ) && cur >= Compress() ) { // Something was moved before the current position and all @@ -292,7 +261,7 @@ void BigPtrArray::Insert( BigPtrEntry* pElem, sal_uLong pos ) p->nEnd++; p->nElem++; m_nSize++; - if( cur != ( m_nBlock - 1 ) ) UpdIndex( cur ); + if( cur != ( m_vpInf.size() - 1 ) ) UpdIndex( cur ); m_nCur = cur; CHECKIDX( ppInf, nBlock, nSize, nCur ); @@ -306,7 +275,7 @@ void BigPtrArray::Remove( sal_uLong pos, sal_uLong n ) sal_uInt16 cur = Index2Block( pos ); // current block number sal_uInt16 nBlk1 = cur; // 1st treated block sal_uInt16 nBlk1del = USHRT_MAX; // 1st deleted block - BlockInfo* p = m_ppInf[ cur ]; + BlockInfo* p = m_vpInf[ cur ]; pos -= p->nStart; sal_uLong nElem = n; @@ -340,7 +309,7 @@ void BigPtrArray::Remove( sal_uLong pos, sal_uLong n ) nElem -= nel; if( !nElem ) break; - p = m_ppInf[ ++cur ]; + p = m_vpInf[ ++cur ]; pos = 0; } @@ -348,17 +317,16 @@ void BigPtrArray::Remove( sal_uLong pos, sal_uLong n ) if( nBlkdel ) { for( sal_uInt16 i = nBlk1del; i < ( nBlk1del + nBlkdel ); i++ ) - delete m_ppInf[ i ]; + delete m_vpInf[ i ]; - if( ( nBlk1del + nBlkdel ) < m_nBlock ) - { - memmove( m_ppInf + nBlk1del, m_ppInf + nBlk1del + nBlkdel, - ( m_nBlock - nBlkdel - nBlk1del ) * sizeof( BlockInfo* ) ); + m_vpInf.erase( m_vpInf.begin() + nBlk1del, m_vpInf.begin() + nBlk1del + nBlkdel ); + if( ( nBlk1del + nBlkdel ) < sal_uInt16(m_vpInf.size()) ) + { // UpdateIdx updates the successor thus start before first elem if( !nBlk1 ) { - p = m_ppInf[ 0 ]; + p = m_vpInf[ 0 ]; p->nStart = 0; p->nEnd = p->nElem-1; } @@ -367,16 +335,15 @@ void BigPtrArray::Remove( sal_uLong pos, sal_uLong n ) --nBlk1; } } - BlockDel( nBlkdel ); // blocks were deleted } m_nSize -= n; - if( nBlk1 != ( m_nBlock - 1 ) && m_nSize ) + if( nBlk1 != ( m_vpInf.size() - 1 ) && m_nSize ) UpdIndex( nBlk1 ); m_nCur = nBlk1; // call Compress() if there is more than 50% space in the array - if( m_nBlock > ( m_nSize / ( MAXENTRY / 2 ) ) ) + if( m_vpInf.size() > ( m_nSize / ( MAXENTRY / 2 ) ) ) Compress(); CHECKIDX( ppInf, nBlock, nSize, nCur ); @@ -386,7 +353,7 @@ void BigPtrArray::Replace( sal_uLong idx, BigPtrEntry* pElem) { assert(idx < m_nSize); // Index out of bounds m_nCur = Index2Block( idx ); - BlockInfo* p = m_ppInf[ m_nCur ]; + BlockInfo* p = m_vpInf[ m_nCur ]; pElem->m_nOffset = sal_uInt16(idx - p->nStart); pElem->m_pBlock = p; p->mvData[ idx - p->nStart ] = pElem; @@ -400,7 +367,7 @@ sal_uInt16 BigPtrArray::Compress() // Iterate over InfoBlock array from beginning to end. If there is a deleted // block in between so move all following ones accordingly. The pointer <pp> // represents the "old" and <qq> the "new" array. - BlockInfo** pp = m_ppInf, **qq = pp; + BlockInfo** pp = m_vpInf.data(), **qq = pp; BlockInfo* p; BlockInfo* pLast(nullptr); // last empty block sal_uInt16 nLast = 0; // missing elements @@ -410,7 +377,7 @@ sal_uInt16 BigPtrArray::Compress() // convert fill percentage into number of remaining elements short const nMax = MAXENTRY - (long) MAXENTRY * COMPRESSLVL / 100; - for( sal_uInt16 cur = 0; cur < m_nBlock; ++cur ) + for( sal_uInt16 cur = 0; cur < sal_uInt16(m_vpInf.size()); ++cur ) { p = *pp++; sal_uInt16 n = p->nElem; @@ -451,6 +418,7 @@ sal_uInt16 BigPtrArray::Compress() // than remove delete p; p = nullptr; + *(pp-1) = nullptr; ++nBlkdel; } else @@ -482,10 +450,11 @@ sal_uInt16 BigPtrArray::Compress() // if blocks were deleted shrink BlockInfo array if needed if( nBlkdel ) - BlockDel( nBlkdel ); + m_vpInf.erase( std::remove_if(m_vpInf.begin(), m_vpInf.end(), [](BlockInfo* bi) { return !bi; }), + m_vpInf.end() ); // and re-index - p = m_ppInf[ 0 ]; + p = m_vpInf[ 0 ]; p->nEnd = p->nElem - 1; UpdIndex( 0 ); diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx index 7d509998ba63..1996f0cec10b 100644 --- a/sw/source/core/docnode/nodes.cxx +++ b/sw/source/core/docnode/nodes.cxx @@ -2185,7 +2185,7 @@ void SwNodes::ForEach( sal_uLong nStart, sal_uLong nEnd, if( nStart < nEnd ) { sal_uInt16 cur = Index2Block( nStart ); - BlockInfo** pp = m_ppInf + cur; + BlockInfo** pp = m_vpInf.data() + cur; BlockInfo* p = *pp; sal_uInt16 nElem = sal_uInt16( nStart - p->nStart ); auto pElem = p->mvData.begin() + nElem; |