LCOV - code coverage report
Current view: top level - sw/source/core/inc - swcache.hxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 43 44 97.7 %
Date: 2015-06-13 12:38:46 Functions: 23 23 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : #ifndef INCLUDED_SW_SOURCE_CORE_INC_SWCACHE_HXX
      20             : #define INCLUDED_SW_SOURCE_CORE_INC_SWCACHE_HXX
      21             : 
      22             : /**
      23             :  * Here, we manage pointers in a simple PtrArray to objects.
      24             :  * These objects are created (using new) in cache access classes; they are
      25             :  * destroyed by the cache.
      26             :  *
      27             :  * One can access these objects by array index or by searching in the array
      28             :  * If you access it by index, managing the index is the responsibility of
      29             :  * the cache user.
      30             :  *
      31             :  * The cached objects are derrived from the base class SwCacheObj.
      32             :  * In it, the cache objects are doubly-linked which allows for the use of
      33             :  * an LRU algorithm.
      34             :  *
      35             :  * The LRU algorithm can be changed in the base class, by setting a virtual
      36             :  * First Pointer. It can be set to the first real one plus an offset.
      37             :  * By doing so we can protect the start area of the cache and make sure we
      38             :  * don't mess up the cache during some special operations.
      39             :  * E.g.: the Idle Handler should not destroy the cache for the visible area.
      40             :  *
      41             :  * The cache can be grown and shrunk in size.
      42             :  * E.g.: The cache for FormatInfo is grown for every new Shell and shrunk
      43             :  * when destroying them.
      44             :  */
      45             : 
      46             : #include <vector>
      47             : 
      48             : #include <rtl/ustring.hxx>
      49             : 
      50             : class SwCacheObj;
      51             : 
      52             : typedef std::vector<SwCacheObj*> SwCacheObjArr;
      53             : class SwCache
      54             : {
      55             :     SwCacheObjArr m_aCacheObjects;
      56             :     std::vector<sal_uInt16> aFreePositions; /// Free positions for the Insert if the maximum has not been reached
      57             :                                             /// Every time an object is deregistered, its position is added here
      58             :     SwCacheObj *pRealFirst;                 /// _ALWAYS_ the real first LRU
      59             :     SwCacheObj *pFirst;                     /// The virtual first
      60             :     SwCacheObj *pLast;
      61             : 
      62             :     sal_uInt16 nCurMax;                     // Maximum of accepted objects
      63             : 
      64             :     void DeleteObj( SwCacheObj *pObj );
      65             : 
      66             : #ifdef DBG_UTIL
      67             :     OString m_aName;
      68             :     long m_nAppend;           /// number of entries appended
      69             :     long m_nInsertFree;       /// number of entries inserted on freed position
      70             :     long m_nReplace;          /// number of LRU replacements
      71             :     long m_nGetSuccess;
      72             :     long m_nGetFail;
      73             :     long m_nToTop;            /// number of reordering (LRU)
      74             :     long m_nDelete;           /// number of explicit deletes
      75             :     long m_nGetSeek;          /// number of gets without index
      76             :     long m_nAverageSeekCnt;   /// number of seeks for all gets without index
      77             :     long m_nFlushCnt;         /// number of flush calls
      78             :     long m_nFlushedObjects;
      79             :     long m_nIncreaseMax;      /// number of cache size increases
      80             :     long m_nDecreaseMax;      /// number of cache size decreases
      81             : 
      82             :     void Check();
      83             : #endif
      84             : 
      85             : public:
      86             : 
      87             : // Only add sal_uInt8!!!
      88             : #ifdef DBG_UTIL
      89             :     SwCache( const sal_uInt16 nInitSize, const OString &rNm );
      90             : #else
      91             :     SwCache( const sal_uInt16 nInitSize );
      92             : #endif
      93             :     /// The dtor will free all objects still in the vector
      94             :     ~SwCache();
      95             : 
      96             :     void Flush( const sal_uInt8 nPercent = 100 );
      97             : 
      98             :     //bToTop == false -> No LRU resorting!
      99             :     SwCacheObj *Get( const void *pOwner, const bool bToTop = true );
     100             :     SwCacheObj *Get( const void *pOwner, const sal_uInt16 nIndex,
     101             :                      const bool bToTop = true );
     102             :     void ToTop( SwCacheObj *pObj );
     103             : 
     104             :     bool Insert( SwCacheObj *pNew );
     105             :     void Delete( const void *pOwner );
     106             : //  void Delete( const void *pOwner, const sal_uInt16 nIndex );
     107             : 
     108             :     void SetLRUOfst( const sal_uInt16 nOfst );  /// nOfst determines how many are not to be touched
     109    26777873 :     void ResetLRUOfst() { pFirst = pRealFirst; }
     110             : 
     111             :     inline void IncreaseMax( const sal_uInt16 nAdd );
     112             :     inline void DecreaseMax( const sal_uInt16 nSub );
     113    26784087 :     sal_uInt16 GetCurMax() const { return nCurMax; }
     114      162190 :     inline SwCacheObj *First() { return pRealFirst; }
     115             :     inline SwCacheObj *Last()  { return pLast; }
     116             :     static inline SwCacheObj *Next( SwCacheObj *pCacheObj);
     117             :     inline SwCacheObj* operator[](sal_uInt16 nIndex) { return m_aCacheObjects[nIndex]; }
     118             :     inline sal_uInt16 size() { return m_aCacheObjects.size(); }
     119             : };
     120             : 
     121             : /// Safely manipulate the cache
     122             : class SwSaveSetLRUOfst
     123             : {
     124             :     SwCache &rCache;
     125             : public:
     126    26777873 :     SwSaveSetLRUOfst( SwCache &rC, const sal_uInt16 nOfst )
     127    26777873 :         : rCache( rC )          { rCache.SetLRUOfst( nOfst );  }
     128             : 
     129    26777873 :     ~SwSaveSetLRUOfst()         { rCache.ResetLRUOfst(); }
     130             : };
     131             : 
     132             : /**
     133             :  * The Cache object base class
     134             :  * Users of the Cache must derrive a class from the SwCacheObj and store
     135             :  * their payload there
     136             :  */
     137             : class SwCacheObj
     138             : {
     139             :     friend class SwCache;   /// Can do everything
     140             : 
     141             :     SwCacheObj *pNext;      /// For the LRU chaining
     142             :     SwCacheObj *pPrev;
     143             : 
     144             :     sal_uInt16 nCachePos;   /// Position in the Cache array
     145             : 
     146             :     sal_uInt8       nLock;
     147             : 
     148     5083516 :     inline SwCacheObj *GetNext() { return pNext; }
     149     1280266 :     inline SwCacheObj *GetPrev() { return pPrev; }
     150      880360 :     inline void SetNext( SwCacheObj *pNew )  { pNext = pNew; }
     151     1132912 :     inline void SetPrev( SwCacheObj *pNew )  { pPrev = pNew; }
     152             : 
     153      113881 :     inline void   SetCachePos( const sal_uInt16 nNew ) { nCachePos = nNew; }
     154             : 
     155             : protected:
     156             :     const void *pOwner;
     157             :     inline void SetOwner( const void *pNew ) { pOwner = pNew; }
     158             : 
     159             : public:
     160             : 
     161             :     SwCacheObj( const void *pOwner );
     162             :     virtual ~SwCacheObj();
     163             : 
     164      286431 :     inline const void *GetOwner() const { return pOwner; }
     165             :     inline bool IsOwner( const void *pNew ) const;
     166             : 
     167      337347 :     inline sal_uInt16 GetCachePos() const { return nCachePos; }
     168             :     inline void Invalidate()          { pOwner = 0; }
     169             : 
     170      114144 :     inline bool IsLocked() const { return 0 != nLock; }
     171             : 
     172             : #ifdef DBG_UTIL
     173             :     void Lock();
     174             :     void Unlock();
     175             : #else
     176     2421296 :     inline void Lock() { ++nLock; }
     177     2421240 :     inline void Unlock() { --nLock; }
     178             : #endif
     179             : 
     180             :     SwCacheObj *Next() { return pNext; }
     181             :     SwCacheObj *Prev() { return pPrev; }
     182             : 
     183             : };
     184             : 
     185             : /**
     186             :  * Access class for the Cache
     187             :  *
     188             :  * The Cache object is created in the ctor.
     189             :  * If the Cache does not return one, the member is set to 0 and one is
     190             :  * created on the Get() and added to the Cache (if possible).
     191             :  * Cache users must derrive a class from SwCacheAccess in order to
     192             :  * guarantee type safety. The base class should always be called for the
     193             :  * Get(). A derrived Get() should only ever guarantee type safety.
     194             :  * Cache objects are always locked for the instance's life time.
     195             :  */
     196             : class SwCacheAccess
     197             : {
     198             :     SwCache &rCache;
     199             : 
     200             :     void _Get();
     201             : 
     202             : protected:
     203             :     SwCacheObj *pObj;
     204             :     const void *pOwner; /// Can be use in NewObj
     205             : 
     206             :     virtual SwCacheObj *NewObj() = 0;
     207             : 
     208             :     inline SwCacheObj *Get();
     209             : 
     210             :     inline SwCacheAccess( SwCache &rCache, const void *pOwner, bool bSeek = true );
     211             :     inline SwCacheAccess( SwCache &rCache, const void *pOwner, const sal_uInt16 nIndex );
     212             : 
     213             : public:
     214             :     virtual ~SwCacheAccess();
     215             : 
     216             :     virtual bool IsAvailable() const;
     217             : 
     218             :     /// Shorthand for those who know that they did not override isAvailable()
     219             :     /// FIXME: wtf?
     220     1142620 :     bool IsAvail() const { return pObj != 0; }
     221             : };
     222             : 
     223        3109 : inline void SwCache::IncreaseMax( const sal_uInt16 nAdd )
     224             : {
     225        3109 :     nCurMax = nCurMax + sal::static_int_cast< sal_uInt16 >(nAdd);
     226             : #ifdef DBG_UTIL
     227             :     ++m_nIncreaseMax;
     228             : #endif
     229        3109 : }
     230        3105 : inline void SwCache::DecreaseMax( const sal_uInt16 nSub )
     231             : {
     232        3105 :     if ( nCurMax > nSub )
     233        3105 :         nCurMax = nCurMax - sal::static_int_cast< sal_uInt16 >(nSub);
     234             : #ifdef DBG_UTIL
     235             :     ++m_nDecreaseMax;
     236             : #endif
     237        3105 : }
     238             : 
     239     4989490 : inline bool SwCacheObj::IsOwner( const void *pNew ) const
     240             : {
     241     4989490 :     return pOwner && pOwner == pNew;
     242             : }
     243             : 
     244      155295 : inline SwCacheObj *SwCache::Next( SwCacheObj *pCacheObj)
     245             : {
     246      155295 :     if ( pCacheObj )
     247      155295 :         return pCacheObj->GetNext();
     248             :     else
     249           0 :         return NULL;
     250             : }
     251             : 
     252      611447 : inline SwCacheAccess::SwCacheAccess( SwCache &rC, const void *pOwn, bool bSeek ) :
     253             :     rCache( rC ),
     254             :     pObj( 0 ),
     255      611447 :     pOwner( pOwn )
     256             : {
     257      611447 :     if ( bSeek && pOwner && 0 != (pObj = rCache.Get( pOwner )) )
     258      531349 :         pObj->Lock();
     259      611447 : }
     260             : 
     261     1252276 : inline SwCacheAccess::SwCacheAccess( SwCache &rC, const void *pOwn,
     262             :                               const sal_uInt16 nIndex ) :
     263             :     rCache( rC ),
     264             :     pObj( 0 ),
     265     1252276 :     pOwner( pOwn )
     266             : {
     267     1252276 :     if ( pOwner && 0 != (pObj = rCache.Get( pOwner, nIndex )) )
     268     1076733 :         pObj->Lock();
     269     1252276 : }
     270             : 
     271     2377639 : inline SwCacheObj *SwCacheAccess::Get()
     272             : {
     273     2377639 :     if ( !pObj )
     274      111175 :         _Get();
     275     2377639 :     return pObj;
     276             : }
     277             : 
     278             : #endif
     279             : 
     280             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11