Commits

Anonymous committed c0a9ddf

itemsets: using static ItemVectors in SwAttrSet for performance

  • Participants
  • Parent commits a032064
  • Branches new_itemsets

Comments (0)

Files changed (4)

File svtools/inc/svtools/itemset.hxx

     protected:
         ::std::vector<sal_uInt16> m_vWhichRanges;
         ::std::auto_ptr< ::sfx::item::ItemVector > m_pItems;
-        bool PutDirect(const SfxPoolItem &rItem);
 
     public:
         typedef int ushort_arg_t;

File svtools/source/items/poolcach.cxx

 	SfxSetItem *pNewItem = (SfxSetItem *)rOrigItem.Clone();
 	if ( pItemToPut )
 	{
-		pNewItem->GetItemSet().PutDirect( *pItemToPut );
+		pNewItem->GetItemSet().Put(*pItemToPut);
 		DBG_ASSERT( &pNewItem->GetItemSet().Get( pItemToPut->Which() ) == pItemToPut,
 					"wrong item in temporary set" );
 	}

File svtools/source/items1/itemset.cxx

     if(nNull)
     {
         va_list pArgs;
-        ushort_arg_t nRangeLimiter;
         va_start(pArgs, nNull);
-        nRangeLimiter = va_arg(pArgs, ushort_arg_t);
         for(ushort_arg_t nRangeLimiter = va_arg(pArgs, ushort_arg_t); nRangeLimiter; nRangeLimiter = va_arg(pArgs, ushort_arg_t))
             m_vWhichRanges.push_back(::sal::static_int_cast<sal_uInt16>(nRangeLimiter));
         va_end(pArgs);
 {
     if(pToPool && pToPool != m_pPool)
     {
-        SfxItemSet *pNewSet = new SfxItemSet(*pToPool, &m_vWhichRanges[0]);
+        SfxItemSet* const pNewSet = new SfxItemSet(*pToPool, &m_vWhichRanges[0]);
+        pNewSet->m_pItems->reserve(m_pItems->size());
         if(bItems)
         {
             for(ItemVector::const_iterator pItemEntry = m_pItems->begin();
             : new SfxItemSet(*m_pPool, &m_vWhichRanges[0]);
 }
 
-bool SfxItemSet::PutDirect(const SfxPoolItem &rItem)
-{
-    if(!lcl_InRange(m_vWhichRanges, rItem.Which()))
-        return false;
-    ItemPosition aItemPosition(m_pItems.get(), rItem.Which());
-    if(aItemPosition.DoesExist())
-    {
-        const SfxPoolItem* pItem = aItemPosition.GetItem();
-        if(pItem == &rItem || *pItem == rItem)
-            return false;
-        aItemPosition.Reset(const_cast<SfxPoolItem*>(&rItem), m_pPool, IsPoolDefaultItem(&rItem));
-    }
-    else
-    {
-        aItemPosition.Create(const_cast<SfxPoolItem*>(&rItem),
-            IsPoolDefaultItem(&rItem) ? m_pPool : NULL);
-    }
-    OSL_POSTCOND(lcl_ValidateItemVector(m_pItems.get(), m_vWhichRanges), "<itemset.cxx> - itemset validation failed.");
-    return true;
-}
-
 SfxAllItemSet::SfxAllItemSet(SfxItemPool& rPool)
     : SfxItemSet(rPool, (const sal_uInt16*) NULL)
 {

File sw/source/core/attr/swatrset.cxx

 using namespace ::sfx::item;
 using namespace ::std;
 
-SwAttrPool::SwAttrPool( SwDoc* pD )
-    : SfxItemPool( String::CreateFromAscii(
-                                RTL_CONSTASCII_STRINGPARAM( "SWG" )),
-                    POOLATTR_BEGIN, POOLATTR_END-1,
-                    aSlotTab, aAttrTab ),
-    pDoc( pD )
+namespace
 {
-    SetVersionMap( 1, 1, 60, pVersionMap1 );
-    SetVersionMap( 2, 1, 75, pVersionMap2 );
-    SetVersionMap( 3, 1, 86, pVersionMap3 );
-    SetVersionMap( 4, 1,121, pVersionMap4 );
+    // static for performance
+    // thus lcl_ChangeTracker is non reentrant
+    static ItemVector vChangeTrackerOldState;
+    class lcl_ChangeTracker
+    {
+        private:
+            const SwAttrSet* const m_pAttrSet;
+
+            const SfxPoolItem& GetDefault(const USHORT nWhich) const
+            {
+                if(!m_pAttrSet->GetParent())
+                    return m_pAttrSet->GetPool()->GetDefaultItem(nWhich);
+                return m_pAttrSet->GetParent()->Get(nWhich, true);
+            };
+
+            void ChangedToDefault(
+                const sfx::item::ItemVector::const_iterator& pItemEntryOld,
+                SwAttrSet* pOld, SwAttrSet* pNew) const
+            {
+                if(!IsInvalidItem(pItemEntryOld->GetItem()))
+                {
+                    // was set, isnt anymore
+                    // ignoring changes from invalid
+                    pOld->Put(*pItemEntryOld->GetItem());
+                    pNew->Put(GetDefault(pItemEntryOld->GetWhich()));
+                }
+            };
+
+            void ChangedFromDefault(
+                const sfx::item::ItemVector::const_iterator& pItemEntryNew,
+                SwAttrSet* pOld, SwAttrSet* pNew) const
+            {
+                if(!IsInvalidItem(pItemEntryNew->GetItem())
+                    && pItemEntryNew->GetItem()->Which())
+                {
+                    // wasnt set, is now
+                    // ignoring changes to invalid
+                    // ignoring disabling
+                    pOld->Put(GetDefault(pItemEntryNew->GetWhich()));
+                    pNew->Put(*pItemEntryNew->GetItem());
+                }
+            };
+        public:
+            lcl_ChangeTracker(const SwAttrSet* const pAttrSet, const ItemVector* const pOldState)
+                : m_pAttrSet(pAttrSet)
+            {
+                vChangeTrackerOldState.clear();
+                copy(pOldState->begin(), pOldState->end(), back_inserter(vChangeTrackerOldState));
+            };
+
+            void MarkChangesForBroadcast(
+                const ItemVector* const pNewState,
+                SwAttrSet* pOld, SwAttrSet* pNew) const
+            {
+                ItemVector::const_iterator pItemEntryOld = vChangeTrackerOldState.begin();
+                ItemVector::const_iterator pItemEntryNew = pNewState->begin();
+                ItemVector::const_iterator pOldEnd = vChangeTrackerOldState.end();
+                ItemVector::const_iterator pNewEnd = pNewState->end();
+                while(pItemEntryOld != pOldEnd &&
+                    pItemEntryNew != pNewEnd)
+                {
+                    if(pItemEntryOld->GetWhich() < pItemEntryNew->GetWhich())
+                        ChangedToDefault(pItemEntryOld++, pOld, pNew);
+                    else if(pItemEntryOld->GetWhich() > pItemEntryNew->GetWhich())
+                        ChangedFromDefault(pItemEntryNew++, pOld, pNew);
+                    else
+                    {
+                        if(pItemEntryOld->GetItem() != pItemEntryNew->GetItem()
+                            && !IsInvalidItem(pItemEntryOld->GetItem())
+                            && !IsInvalidItem(pItemEntryNew->GetItem())
+                            && pItemEntryNew->GetItem()->Which())
+                        {
+                            // ignoring changes from/to invalid
+                            // ignoring disabling
+                            pOld->Put(*pItemEntryOld->GetItem());
+                            pNew->Put(*pItemEntryNew->GetItem());
+                        }
+                        ++pItemEntryOld, ++pItemEntryNew;
+                    }
+                }
+                while(pItemEntryOld != pOldEnd)
+                    ChangedToDefault(pItemEntryOld++, pOld, pNew);
+                while(pItemEntryNew != pNewEnd)
+                    ChangedFromDefault(pItemEntryNew++, pOld, pNew);
+            };
+    };
+}
+
+SwAttrPool::SwAttrPool(SwDoc* pD)
+    : SfxItemPool(
+        String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "SWG" )),
+        POOLATTR_BEGIN, POOLATTR_END-1,
+        aSlotTab, aAttrTab),
+    pDoc(pD)
+{
+    SetVersionMap(1, 1, 60, pVersionMap1);
+    SetVersionMap(2, 1, 75, pVersionMap2);
+    SetVersionMap(3, 1, 86, pVersionMap3);
+    SetVersionMap(4, 1, 121, pVersionMap4);
     // OD 2004-01-21 #i18732# - apply new version map
-    SetVersionMap( 5, 1,130, pVersionMap5 );
-    SetVersionMap( 6, 1,136, pVersionMap6 );
+    SetVersionMap(5, 1, 130, pVersionMap5);
+    SetVersionMap(6, 1, 136, pVersionMap6);
 }
 
 SwAttrPool::~SwAttrPool()
 {
 }
 
-SwAttrSet::SwAttrSet( SwAttrPool& rPool, USHORT nWh1, USHORT nWh2 )
-    : SfxItemSet( rPool, nWh1, nWh2 )
+SwAttrSet::SwAttrSet(SwAttrPool& rPool, USHORT nWh1, USHORT nWh2)
+    : SfxItemSet(rPool, nWh1, nWh2)
 {
 }
 
 
-SwAttrSet::SwAttrSet( SwAttrPool& rPool, const USHORT* nWhichPairTable )
-    : SfxItemSet( rPool, nWhichPairTable )
+SwAttrSet::SwAttrSet(SwAttrPool& rPool, const USHORT* nWhichPairTable)
+    : SfxItemSet(rPool, nWhichPairTable)
 {
 }
 
 
-SwAttrSet::SwAttrSet( const SwAttrSet& rSet )
-    : SfxItemSet( rSet )
+SwAttrSet::SwAttrSet(const SwAttrSet& rSet)
+    : SfxItemSet(rSet)
 {
 }
 
-SfxItemSet* SwAttrSet::Clone( bool bItems, SfxItemPool *pToPool ) const
+SfxItemSet* SwAttrSet::Clone(bool bItems, SfxItemPool *pToPool) const
 {
-    if ( pToPool && pToPool != GetPool() )
+    if(pToPool && pToPool != GetPool())
     {
-        SwAttrPool* pAttrPool = dynamic_cast< SwAttrPool* >(pToPool);
-        SfxItemSet* pTmpSet = 0;
-        if ( !pAttrPool )
-            pTmpSet = SfxItemSet::Clone( bItems, pToPool );
+        SwAttrPool* pAttrPool = dynamic_cast<SwAttrPool*>(pToPool);
+        SfxItemSet* pTmpSet = NULL;
+        if(!pAttrPool)
+            pTmpSet = SfxItemSet::Clone(bItems, pToPool);
         else
         {
-            pTmpSet = new SwAttrSet( *pAttrPool, GetRanges() );
-            if ( bItems )
+            pTmpSet = new SwAttrSet(*pAttrPool, GetRanges());
+            if(bItems)
             {
                 for(ItemVector::const_iterator pItemEntry = m_pItems->begin();
                     pItemEntry != m_pItems->end();
     }
     else
         return bItems
-                ? new SwAttrSet( *this )
-                : new SwAttrSet( *GetPool(), GetRanges() );
+            ? new SwAttrSet(*this)
+            : new SwAttrSet(*GetPool(), GetRanges());
 }
 
-inline void SwAttrSet::ChangedToDefault(
-    const sfx::item::ItemVector::const_iterator& pItemEntryOld,
-    SwAttrSet* pOld, SwAttrSet* pNew)
-{
-    if(!IsInvalidItem(pItemEntryOld->GetItem()))
-    {
-        // was set, isnt anymore
-        // ignoring changes from invalid
-        pOld->PutDirect(*pItemEntryOld->GetItem());
-        pNew->PutDirect(GetParent()
-            ? GetParent()->Get(pItemEntryOld->GetWhich(), true)
-            : GetPool()->GetDefaultItem(pItemEntryOld->GetWhich()));
-    }
-};
-
-inline void SwAttrSet::ChangedFromDefault(
-    const sfx::item::ItemVector::const_iterator& pItemEntryNew,
-    SwAttrSet* pOld, SwAttrSet* pNew)
-{
-    if(!IsInvalidItem(pItemEntryNew->GetItem())
-        && pItemEntryNew->GetItem()->Which())
-    {
-        // wasnt set, is now
-        // ignoring changes to invalid
-        // ignoring disabling
-        pOld->PutDirect(GetParent()
-            ? GetParent()->Get(pItemEntryNew->GetWhich(), true)
-            : GetPool()->GetDefaultItem(pItemEntryNew->GetWhich()));
-        pNew->PutDirect(*pItemEntryNew->GetItem());
-    }
-};
-
-inline void SwAttrSet::MarkChangesForBroadcast(
-    const SwAttrSet* const pOldState,
-    SwAttrSet* pOld, SwAttrSet* pNew)
-{
-    ItemVector::const_iterator pItemEntryOld = pOldState->m_pItems->begin();
-    ItemVector::const_iterator pItemEntryNew = m_pItems->begin();
-    ItemVector::const_iterator pOldEnd = pOldState->m_pItems->end();
-    ItemVector::const_iterator pNewEnd = m_pItems->end();
-    while(pItemEntryOld != pOldEnd &&
-        pItemEntryNew != pNewEnd)
-    {
-        if(pItemEntryOld->GetWhich() < pItemEntryNew->GetWhich())
-            ChangedToDefault(pItemEntryOld++, pOld, pNew);
-        else if(pItemEntryOld->GetWhich() > pItemEntryNew->GetWhich())
-            ChangedFromDefault(pItemEntryNew++, pOld, pNew);
-        else
-        {
-            if(pItemEntryOld->GetItem() != pItemEntryNew->GetItem()
-                && !IsInvalidItem(pItemEntryOld->GetItem())
-                && !IsInvalidItem(pItemEntryNew->GetItem())
-                && pItemEntryNew->GetItem()->Which())
-            {
-                // ignoring changes from/to invalid
-                // ignoring disabling
-                pOld->PutDirect(*pItemEntryOld->GetItem());
-                pNew->PutDirect(*pItemEntryNew->GetItem());
-            }
-            ++pItemEntryOld, ++pItemEntryNew;
-        }
-    }
-    while(pItemEntryOld != pOldEnd)
-        ChangedToDefault(pItemEntryOld++, pOld, pNew);
-    while(pItemEntryNew != pNewEnd)
-        ChangedFromDefault(pItemEntryNew++, pOld, pNew);
-}
 
 int SwAttrSet::Put_BC(const SfxPoolItem& rAttr,
     SwAttrSet* pOld, SwAttrSet* pNew)
 {
     if(!pOld)
         return (Put(rAttr) != NULL);
-    const SwAttrSet aOldState(*this);
+    const lcl_ChangeTracker aChangeTracker(this, m_pItems.get());
 	const bool nResult = Put(rAttr);
-    MarkChangesForBroadcast(&aOldState, pOld, pNew);
+    aChangeTracker.MarkChangesForBroadcast(m_pItems.get(), pOld, pNew);
 	return nResult;
 }
 
 {
     if(!pOld)
         return Put(rSet);
-    const SwAttrSet aOldState(*this);
+    const lcl_ChangeTracker aChangeTracker(this, m_pItems.get());
 	const bool nResult = Put(rSet);
-    MarkChangesForBroadcast(&aOldState, pOld, pNew);
+    aChangeTracker.MarkChangesForBroadcast(m_pItems.get(), pOld, pNew);
 	return nResult;
 }
 
 {
     if(!pOld)
         return ClearItem(nWhich);
-    const SwAttrSet aOldState(*this);
+    const lcl_ChangeTracker aChangeTracker(this, m_pItems.get());
 	const USHORT nResult = ClearItem(nWhich);
-    MarkChangesForBroadcast(&aOldState, pOld, pNew);
+    aChangeTracker.MarkChangesForBroadcast(m_pItems.get(), pOld, pNew);
     return nResult;
 }
 
             nRet = nRet + ClearItem(nWhich1);
         return nRet;
     }
-    const SwAttrSet aOldState(*this);
+    const lcl_ChangeTracker aChangeTracker(this, m_pItems.get());
 	for(; nWhich1 <= nWhich2; ++nWhich1)
 		nRet = nRet + ClearItem(nWhich1);
-    MarkChangesForBroadcast(&aOldState, pOld, pNew);
+    aChangeTracker.MarkChangesForBroadcast(m_pItems.get(), pOld, pNew);
     return nRet;
 }
 
         Intersect(rSet);
         return 0;
     }
-    const SwAttrSet aOldState(*this);
+    const lcl_ChangeTracker aChangeTracker(this, m_pItems.get());
 	Intersect(rSet);
-    MarkChangesForBroadcast(&aOldState, pOld, pNew);
+    aChangeTracker.MarkChangesForBroadcast(m_pItems.get(), pOld, pNew);
 	return pOld->Count(); //FIXME
 }