summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2014-05-14 15:03:53 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2014-09-30 09:56:34 +0200
commit04221432f265cace36f536bbe6cbfd25498b120f (patch)
tree113b9a08d20951285babdf8e1e1fa33b0b772d15
parentdd2aad957d1b65d9a3d0920ef558f0da071f9aa0 (diff)
Optimize SwPageDesc lookup by pool ID
There are just ten default page pool style IDs. So instead of walking the whole style list to find the matching style ID, this introduces an additional index / array for faster lookup. (cherry picked from commit 3cd2f4c974f9119e920a75a00d194641c2808c94) Conflicts: sw/source/core/doc/docdesc.cxx sw/source/core/doc/poolfmt.cxx sw/source/core/layout/pagedesc.cxx sw/source/filter/html/htmlcss1.cxx Change-Id: Iacfa40c76e5502dc90665be0a96388de50d5ec16
-rw-r--r--sw/inc/doc.hxx1
-rw-r--r--sw/inc/pagedesc.hxx21
-rw-r--r--sw/source/core/doc/docdesc.cxx5
-rw-r--r--sw/source/core/doc/poolfmt.cxx11
-rw-r--r--sw/source/core/layout/pagedesc.cxx81
-rw-r--r--sw/source/filter/html/htmlcss1.cxx19
-rw-r--r--sw/source/filter/html/htmlsect.cxx9
7 files changed, 110 insertions, 37 deletions
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 3de7ef178816..dbab8734ed59 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1354,6 +1354,7 @@ public:
SwPageDesc& GetPageDesc( sal_uInt16 i ) { return *maPageDescs[i]; }
SwPageDesc* FindPageDescByName( const OUString& rName, sal_uInt16* pPos = 0 ) const;
SwPageDesc* FindPageDescByName( const OUString& rName, sal_uInt16* pPos = 0 );
+ SwPageDesc* FindPageDescByPoolId( sal_uInt16 nPoolId );
/** Copy the complete PageDesc - beyond document and "deep"!
Optionally copying of PoolFmtId, -HlpId can be prevented. */
diff --git a/sw/inc/pagedesc.hxx b/sw/inc/pagedesc.hxx
index 0510a63cf9c6..1b6da4ac30d7 100644
--- a/sw/inc/pagedesc.hxx
+++ b/sw/inc/pagedesc.hxx
@@ -26,6 +26,7 @@
#include <frmfmt.hxx>
#include <editeng/numitem.hxx>
#include <editeng/borderline.hxx>
+#include "poolfmt.hxx"
class SfxPoolItem;
class SwTxtFmtColl;
@@ -233,7 +234,7 @@ public:
/// Query and set PoolFormat-Id.
sal_uInt16 GetPoolFmtId() const { return aMaster.GetPoolFmtId(); }
- void SetPoolFmtId( sal_uInt16 nId ) { aMaster.SetPoolFmtId( nId ); }
+ void SetPoolFmtId( sal_uInt16 nId );
sal_uInt16 GetPoolHelpId() const { return aMaster.GetPoolHelpId(); }
void SetPoolHelpId( sal_uInt16 nId ) { aMaster.SetPoolHelpId( nId ); }
sal_uInt8 GetPoolHlpFileId() const { return aMaster.GetPoolHlpFileId(); }
@@ -345,15 +346,30 @@ public:
typedef std::vector<SwPageDesc*> SwPageDescsBase;
-// PageDescriptor-interface, Array because of inlines.
+#define RES_POOLPAGE_SIZE (RES_POOLPAGE_END - RES_POOLPAGE_BEGIN)
+
// Mimics o3tl::sorted_vector interface
class SwPageDescs : private SwPageDescsBase
{
+ // to update the poolpages array on PoolFmtId change
+ friend void SwPageDesc::SetPoolFmtId( sal_uInt16 nId );
+
public:
typedef SwPageDescsBase::const_iterator const_iterator;
typedef SwPageDescsBase::size_type size_type;
typedef SwPageDescsBase::value_type value_type;
+private:
+ // fast index for pool page resources
+ value_type poolpages[RES_POOLPAGE_SIZE];
+
+ void _erase( const value_type& x );
+ bool IsIdInPoolRange( sal_uInt16 nId, bool allowDefault ) const;
+
+ bool SetPoolPageDesc( const value_type& x, sal_uInt16 nId = USHRT_MAX );
+
+public:
+ SwPageDescs();
// the destructor will free all objects still in the vector
~SwPageDescs();
@@ -380,6 +396,7 @@ public:
const_iterator end() const { return SwPageDescsBase::end(); }
bool Contains( const value_type& x ) const;
+ value_type GetPoolPageDesc( sal_uInt16 nId ) const;
private:
typedef SwPageDescsBase::iterator iterator;
diff --git a/sw/source/core/doc/docdesc.cxx b/sw/source/core/doc/docdesc.cxx
index 9b79b7366ce5..2ce87c4daf59 100644
--- a/sw/source/core/doc/docdesc.cxx
+++ b/sw/source/core/doc/docdesc.cxx
@@ -854,6 +854,11 @@ SwPageDesc* SwDoc::FindPageDescByName( const OUString & rName, sal_uInt16* pPos
return lcl_FindPageDescByName( const_cast <SwPageDescs *>( &maPageDescs ), rName, pPos );
}
+SwPageDesc* SwDoc::FindPageDescByPoolId( sal_uInt16 nPoolId )
+{
+ return maPageDescs.GetPoolPageDesc( nPoolId );
+}
+
void SwDoc::DelPageDesc( const String & rName, bool bBroadcast )
{
SwPageDesc *pd = FindPageDescByName(rName);
diff --git a/sw/source/core/doc/poolfmt.cxx b/sw/source/core/doc/poolfmt.cxx
index 01e6ee74aea8..0f3665ba4a62 100644
--- a/sw/source/core/doc/poolfmt.cxx
+++ b/sw/source/core/doc/poolfmt.cxx
@@ -1423,14 +1423,9 @@ SwPageDesc* SwDoc::GetPageDescFromPool( sal_uInt16 nId, bool bRegardLanguage )
OSL_ENSURE( RES_POOLPAGE_BEGIN <= nId && nId < RES_POOLPAGE_END,
"Wrong AutoFormat Id" );
- SwPageDesc *pNewPgDsc;
- sal_uInt16 n;
-
- for( n = 0; n < maPageDescs.size(); ++n )
- if( nId == ( pNewPgDsc = maPageDescs[ n ] )->GetPoolFmtId() )
- {
- return pNewPgDsc;
- }
+ SwPageDesc* pNewPgDsc = maPageDescs.GetPoolPageDesc( nId );
+ if (pNewPgDsc)
+ return pNewPgDsc;
// error: unknown Pool style
if( RES_POOLPAGE_BEGIN > nId || nId >= RES_POOLPAGE_END )
diff --git a/sw/source/core/layout/pagedesc.cxx b/sw/source/core/layout/pagedesc.cxx
index 61d3d1af24d9..d1af6afb4a0d 100644
--- a/sw/source/core/layout/pagedesc.cxx
+++ b/sw/source/core/layout/pagedesc.cxx
@@ -294,6 +294,19 @@ void SwPageDesc::RegisterChange()
}
}
+void SwPageDesc::SetPoolFmtId( sal_uInt16 nId )
+{
+ sal_uInt16 nIdOld = aMaster.GetPoolFmtId();
+ if ( nId == nIdOld )
+ return;
+ aMaster.SetPoolFmtId( nId );
+ if (list != 0) {
+ bool ok = list->SetPoolPageDesc( this, nIdOld );
+ SAL_WARN_IF(!ok, "sw",
+ "Unable to set register the PoolFmtId from SetPoolFmtId");
+ }
+}
+
/*************************************************************************
|*
|* SwPageDesc::Modify()
@@ -302,7 +315,6 @@ void SwPageDesc::RegisterChange()
|*
*************************************************************************/
-
void SwPageDesc::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
{
const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
@@ -542,6 +554,11 @@ SwPageDescExt::operator SwPageDesc() const
return aResult;
}
+SwPageDescs::SwPageDescs()
+{
+ memset(poolpages, 0, sizeof(value_type) * RES_POOLPAGE_SIZE);
+}
+
SwPageDescs::~SwPageDescs()
{
DeleteAndDestroyAll();
@@ -551,27 +568,49 @@ void SwPageDescs::DeleteAndDestroyAll()
{
for( const_iterator it = begin(); it != end(); ++it )
delete *it;
+ memset(poolpages, 0, sizeof(value_type) * RES_POOLPAGE_SIZE);
clear();
}
std::pair<SwPageDescs::const_iterator,bool> SwPageDescs::insert( const value_type& x )
{
+ sal_uInt16 nId = x->GetPoolFmtId();
+ SAL_WARN_IF(nId != USHRT_MAX && NULL != GetPoolPageDesc( nId ),
+ "sw", "Inserting already assigned pool ID item!");
+
const_iterator const ret = find( x );
if (ret == end()) {
SwPageDescsBase::push_back( x );
- SAL_WARN_IF(x->list == 0, "sw", "Inserting already assigned item");
+ if (x->list != 0) {
+ SAL_WARN("sw", "Inserting already assigned item!");
+ SAL_WARN_IF(x->list != this, "sw",
+ "Inserting assigned item from other list!");
+ }
x->list = this;
+ if (nId != USHRT_MAX)
+ poolpages[ nId - RES_POOLPAGE_BEGIN ] = x;
return std::make_pair(end() - 1 , true);
}
return std::make_pair(ret, false);
}
+void SwPageDescs::_erase( const value_type& x )
+{
+ sal_uInt16 nId = x->GetPoolFmtId();
+ if (nId != USHRT_MAX) {
+ SAL_WARN_IF(poolpages[ nId - RES_POOLPAGE_BEGIN ] != x,
+ "sw", "SwPageDesc with PoolId not correctly registered!");
+ poolpages[ nId - RES_POOLPAGE_BEGIN ] = NULL;
+ }
+ x->list = 0;
+}
+
SwPageDescs::size_type SwPageDescs::erase( const value_type& x )
{
const_iterator const ret = find( x );
if (ret != end()) {
SwPageDescsBase::erase( begin_nonconst() + (ret - begin()) );
- x->list = 0;
+ _erase( x );
return 1;
}
return 0;
@@ -584,7 +623,7 @@ void SwPageDescs::erase( size_type index )
void SwPageDescs::erase( const_iterator const& position )
{
- (*position)->list = 0;
+ _erase( *position );
SwPageDescsBase::erase( begin_nonconst() + (position - begin()) );
}
@@ -623,4 +662,38 @@ bool SwPageDescs::Contains( const SwPageDescs::value_type& x ) const
return (x->list == this);
}
+bool SwPageDescs::IsIdInPoolRange( sal_uInt16 nId, bool allowDefault ) const
+{
+ bool res = (nId >= RES_POOLPAGE_BEGIN && nId < RES_POOLPAGE_END);
+ if (!res && allowDefault)
+ res = (nId == USHRT_MAX);
+ SAL_WARN_IF(!res, "sw", "PageDesc pool id out of range");
+ return res;
+}
+
+bool SwPageDescs::SetPoolPageDesc( const value_type& x, sal_uInt16 nIdOld )
+{
+ sal_uInt16 nId = x->GetPoolFmtId();
+ if (!IsIdInPoolRange(nIdOld, true)) return false;
+ if (!IsIdInPoolRange(nId, true)) return false;
+
+ if (nIdOld != USHRT_MAX) {
+ SAL_WARN_IF(x != poolpages[ nIdOld - RES_POOLPAGE_BEGIN ],
+ "sw", "Old PageDesc pool id pointer != object");
+ poolpages[ nIdOld - RES_POOLPAGE_BEGIN ] = NULL;
+ }
+ if (nId != USHRT_MAX) {
+ SAL_WARN_IF(NULL != poolpages[ nId - RES_POOLPAGE_BEGIN ],
+ "sw", "SwPageDesc pool ID already assigned!");
+ poolpages[ nId - RES_POOLPAGE_BEGIN ] = x;
+ }
+ return true;
+}
+
+SwPageDescs::value_type SwPageDescs::GetPoolPageDesc( sal_uInt16 nId ) const
+{
+ if (!IsIdInPoolRange(nId, false)) return NULL;
+ return poolpages[ nId - RES_POOLPAGE_BEGIN ];
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/htmlcss1.cxx b/sw/source/filter/html/htmlcss1.cxx
index 5f00b0cb7960..c8a58ee7fb70 100644
--- a/sw/source/filter/html/htmlcss1.cxx
+++ b/sw/source/filter/html/htmlcss1.cxx
@@ -1353,30 +1353,19 @@ SwPageDesc *SwCSS1Parser::GetMasterPageDesc()
return pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false );
}
-static SwPageDesc *FindPageDesc( SwDoc *pDoc, sal_uInt16 nPoolId, sal_uInt16& rPage )
-{
- sal_uInt16 nPageDescs = pDoc->GetPageDescCnt();
- for( rPage=0; rPage < nPageDescs &&
- pDoc->GetPageDesc(rPage).GetPoolFmtId() != nPoolId; rPage++ )
- ;
-
- return rPage < nPageDescs ? &pDoc->GetPageDesc( rPage ) : 0;
-}
-
const SwPageDesc *SwCSS1Parser::GetPageDesc( sal_uInt16 nPoolId, sal_Bool bCreate )
{
if( RES_POOLPAGE_HTML == nPoolId )
return pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false );
- sal_uInt16 nPage;
- const SwPageDesc *pPageDesc = FindPageDesc( pDoc, nPoolId, nPage );
+ const SwPageDesc *pPageDesc = pDoc->FindPageDescByPoolId( nPoolId );
if( !pPageDesc && bCreate )
{
// Die erste Seite wird aus der rechten Seite erzeugt, wenn es die
// gibt.
SwPageDesc *pMasterPageDesc = 0;
if( RES_POOLPAGE_FIRST == nPoolId )
- pMasterPageDesc = FindPageDesc( pDoc, RES_POOLPAGE_RIGHT, nPage );
+ pMasterPageDesc = pDoc->FindPageDescByPoolId( RES_POOLPAGE_RIGHT );
if( !pMasterPageDesc )
pMasterPageDesc = pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false );
@@ -1385,8 +1374,8 @@ const SwPageDesc *SwCSS1Parser::GetPageDesc( sal_uInt16 nPoolId, sal_Bool bCreat
GetPageDescFromPool( nPoolId, false );
// dazu brauchen wir auch die Nummer der neuen Vorlage
- pPageDesc = FindPageDesc( pDoc, nPoolId, nPage );
- OSL_ENSURE( pPageDesc==pNewPageDesc, "Seitenvorlage nicht gefunden" );
+ pPageDesc = pDoc->FindPageDescByPoolId( nPoolId );
+ OSL_ENSURE( pPageDesc == pNewPageDesc, "Seitenvorlage nicht gefunden" );
pDoc->CopyPageDesc( *pMasterPageDesc, *pNewPageDesc, false );
diff --git a/sw/source/filter/html/htmlsect.cxx b/sw/source/filter/html/htmlsect.cxx
index b9e76dac8df5..56f24e8d6e2e 100644
--- a/sw/source/filter/html/htmlsect.cxx
+++ b/sw/source/filter/html/htmlsect.cxx
@@ -202,14 +202,7 @@ void SwHTMLParser::NewDivision( int nToken )
pDoc->DelFullPara( aDelPam );
// Die Seitenvorlage aktualisieren
- for( sal_uInt16 i=0; i < pDoc->GetPageDescCnt(); i++ )
- {
- if( RES_POOLPAGE_HTML == pDoc->GetPageDesc(i).GetPoolFmtId() )
- {
- pDoc->ChgPageDesc( i, *pPageDesc );
- break;
- }
- }
+ pDoc->ChgPageDescP( *pDoc->FindPageDescByPoolId( RES_POOLPAGE_HTML ) );
}
SwPosition aNewPos( SwNodeIndex( rCntntStIdx, 1 ), SwIndex( pCNd, 0 ) );