Files
libreoffice/sw/source/core/inc/swcache.hxx

311 lines
9.7 KiB
C++
Raw Normal View History

2000-09-18 23:08:29 +00:00
/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
2000-09-18 23:08:29 +00:00
*
* $RCSfile: swcache.hxx,v $
2000-09-18 23:08:29 +00:00
*
* $Revision: 1.5 $
2000-09-18 23:08:29 +00:00
*
* last change: $Author: hr $ $Date: 2007-09-27 08:58:37 $
2000-09-18 23:08:29 +00:00
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
2000-09-18 23:08:29 +00:00
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
2000-09-18 23:08:29 +00:00
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
2000-09-18 23:08:29 +00:00
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
2000-09-18 23:08:29 +00:00
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
2000-09-18 23:08:29 +00:00
*
************************************************************************/
#ifndef _SWCACHE_HXX
#define _SWCACHE_HXX
/*
* Es werden Pointer auf Objekte verwaltet. Diese werden in einem einfachen
* PtrArray verwaltet.
* Angelegt (new) werden die Objekte von Cache-Zugriffsklassen, zuerstoert
* werden die Objekte vom Cache.
*
* Auf die Objekte kann wahlweise per Index in das Array oder per Suche
* zugegriffen werden. Soll per Index zugegriffen werden, so obliegt die
* Verwaltung des Index dem Anwender des Cache.
*
* Fuer die verwalteten Cache-Objekte gibt es eine Basisklasse, von dieser
* sind spezifische Klassen abzuleiten.
* In der Basisklasse werden die Cache-Objekte eines Cache doppelt verkettet,
* das ermoeglich die Implementierung eines LRU-Algorithmus.
*
* Der LRU kann in der Cache-Basisklasse manipuliert werden, indem ein
* virtueller First-Pointer gesetzt wird. Dieser kann auf den echten ersten
* plus einem Ofst gesetzt werden. Dadurch kann man den Anfangsbereich des
* Cache sichern und so dafuer sorgen, dass man waehrend bestimmter
* Operationen nicht den Cache versaut. Beispiel: Der Idle-Handler sollte nicht
* den Cache fuer den sichtbaren Bereich vernichten.
*
* Der Cache kann in der Groesse erweitert und wieder verkleinert werden.
* Beispiel: Fuer jede neue Shell wird der Cache fuer FormatInfo vergrossert
* und beim Destruieren der Shell wieder verkleinert.
*
*/
#ifndef PRODUCT
#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif
#endif
#ifndef _SVSTDARR_HXX
#define _SVSTDARR_USHORTS
#include <svtools/svstdarr.hxx>
#endif
class SwCacheObj;
SV_DECL_PTRARR_DEL(SwCacheObjArr,SwCacheObj*,1,1)
class SwCache : public SwCacheObjArr
{
SvUShorts aFreePositions; //Freie Positionen fuer das Insert wenn
//die Maximalgrenze nicht erreicht ist.
//Immer wenn ein Objekt ausgetragen wird,
//so wird seine Position hier eingetragen.
SwCacheObj *pRealFirst; //_immer_ der echte LRU-erste
SwCacheObj *pFirst; //der virtuelle erste.
SwCacheObj *pLast;
const USHORT nMax; //Mehr sollen nicht aufgenommen werden,
//der Cache kann aber dynamisch um jeweils
//nMax vergroessert werden.
USHORT nCurMax; //Mehr werden nicht aufgenommen.
void DeleteObj( SwCacheObj *pObj );
#ifndef PRODUCT
ByteString aName;
long nAppend; //Anzahl der Eintragungen durch Erweiterung.
long nInsertFree; //Anzahl der Eintragungen auf freie Plaetze.
long nReplace; //Anzahl der Ersetzungen durch ein neues Objekt
long nGetSuccess; //Anzahl der Erfolgreichen Get's
long nGetFail; //Anzahl der nicht Erfolgreichen Get's
long nToTop; //Anzahl der Umsortierungen (LRU)
long nDelete; //Anzahl der Loeschungen (von Aussen)
long nGetSeek; //Anzahl der Get's ohne Index
long nAverageSeekCnt; //Anzahl der Seek's fuer alle Get's ohne Index
long nFlushCnt; //Anzahl von Flush-Aufrufen.
long nFlushedObjects; //Anzahl der wg. Flush vernichteten Objekte
long nIncreaseMax; //Anzahl Cache-Erweiterungen
long nDecreaseMax; //Anzahl Cache-Verkleinerungen
void Check(); //Wird bei swcache.cxx mit DEBUG aktiv!
#endif
public:
//nur BYTE hineinstecken!!!
#ifndef PRODUCT
SwCache( const USHORT nInitSize, const USHORT nGrowSize,
const ByteString &rNm );
~SwCache();
#else
SwCache( const USHORT nInitSize, const USHORT nGrowSize );
#endif
void Flush( const BYTE nPercent = 100 );
//bToTop == FALSE -> Keine LRU-Umsortierung!
SwCacheObj *Get( const void *pOwner, const BOOL bToTop = TRUE );
SwCacheObj *Get( const void *pOwner, const USHORT nIndex,
const BOOL bToTop = TRUE );
void ToTop( SwCacheObj *pObj );
BOOL Insert( SwCacheObj *pNew );
void Delete( const void *pOwner );
// void Delete( const void *pOwner, const USHORT nIndex );
void SetLRUOfst( const USHORT nOfst ); //nOfst sagt wieviele unangetastet
//bleiben sollen.
void ResetLRUOfst() { pFirst = pRealFirst; }
inline void IncreaseMax( const USHORT nAdd );
inline void DecreaseMax( const USHORT nSub );
USHORT GetCurMax() const { return nCurMax; }
inline SwCacheObj *First() { return pRealFirst; }
inline SwCacheObj *Last() { return pLast; }
inline SwCacheObj *Next( SwCacheObj *pCacheObj);
};
//Cache-Manipulation auf die sichere Art.
class SwSaveSetLRUOfst
{
SwCache &rCache;
public:
SwSaveSetLRUOfst( SwCache &rC, const USHORT nOfst )
: rCache( rC ) { rCache.SetLRUOfst( nOfst ); }
~SwSaveSetLRUOfst() { rCache.ResetLRUOfst(); }
};
//Das allgemeine CacheObjekt. Anwender des Cache muessen eine Klasse vom
//CacheObjekt ableiten und dort die Nutzdaten unterbringen.
class SwCacheObj
{
friend class SwCache; //Der darf alles
SwCacheObj *pNext; //Fuer die LRU-Verkettung.
SwCacheObj *pPrev;
USHORT nCachePos; //Position im Cache-Array.
BYTE nLock;
inline SwCacheObj *GetNext() { return pNext; }
inline SwCacheObj *GetPrev() { return pPrev; }
inline void SetNext( SwCacheObj *pNew ) { pNext = pNew; }
inline void SetPrev( SwCacheObj *pNew ) { pPrev = pNew; }
inline void SetCachePos( const USHORT nNew ) { nCachePos = nNew; }
protected:
const void *pOwner;
inline void SetOwner( const void *pNew ) { pOwner = pNew; }
public:
SwCacheObj( const void *pOwner );
virtual ~SwCacheObj();
inline const void *GetOwner() const { return pOwner; }
inline BOOL IsOwner( const void *pNew ) const;
inline USHORT GetCachePos() const { return nCachePos; }
inline void Invalidate() { pOwner = 0; }
inline BOOL IsLocked() const { return 0 != nLock; }
#ifdef PRODUCT
inline void Lock() { ++nLock; }
inline void Unlock() { --nLock; }
#else
void Lock();
void Unlock();
#endif
SwCacheObj *Next() { return pNext; }
SwCacheObj *Prev() { return pPrev; }
};
//Zugriffsklasse fuer den Cache. Im CTor wird das CacheObjekt erzeugt.
//Wenn der Cache keines herausrueckt wird der Member zunaechst auf 0 gesetzt.
//Beim Get wird dann eines erzeugt und, falls moeglich, in den Cache
//eingetragen.
//Anwender der des Cache muessen eine Klasse vom Access ableiten um
//fuer Typsicherheit zu sorgen, die Basisklasse sollte fuer das Get aber immer
//gerufen werden, ein Abgeleitetes Get sollte nur der Typsicherheit dienen.
//Cache-Objekte werden stets gelockt solange die Instanz lebt.
class SwCacheAccess
{
SwCache &rCache;
void _Get();
protected:
SwCacheObj *pObj;
const void *pOwner; //Kann ggf. in NewObj benutzt werden.
virtual SwCacheObj *NewObj() = 0;
inline SwCacheObj *Get();
inline SwCacheAccess( SwCache &rCache, const void *pOwner, BOOL bSeek = TRUE );
inline SwCacheAccess( SwCache &rCache, const void *pOwner, const USHORT nIndex );
public:
virtual ~SwCacheAccess();
2000-09-18 23:08:29 +00:00
virtual BOOL IsAvailable() const;
//Abkuerzung fuer diejenigen, die wissen, das die Ableitung das IsAvailable
//nicht ueberladen haben.
BOOL IsAvail() const { return pObj != 0; }
};
inline void SwCache::IncreaseMax( const USHORT nAdd )
{
nCurMax = nCurMax + sal::static_int_cast< USHORT >(nAdd);
2000-09-18 23:08:29 +00:00
#ifndef PRODUCT
++nIncreaseMax;
#endif
}
inline void SwCache::DecreaseMax( const USHORT nSub )
{
if ( nCurMax > nSub )
nCurMax = nCurMax - sal::static_int_cast< USHORT >(nSub);
2000-09-18 23:08:29 +00:00
#ifndef PRODUCT
++nDecreaseMax;
#endif
}
inline BOOL SwCacheObj::IsOwner( const void *pNew ) const
{
return pOwner && pOwner == pNew;
}
inline SwCacheObj *SwCache::Next( SwCacheObj *pCacheObj)
{
if ( pCacheObj )
return pCacheObj->GetNext();
else
return NULL;
}
inline SwCacheAccess::SwCacheAccess( SwCache &rC, const void *pOwn, BOOL bSeek ) :
rCache( rC ),
pObj( 0 ),
pOwner( pOwn )
2000-09-18 23:08:29 +00:00
{
if ( bSeek && pOwner && 0 != (pObj = rCache.Get( pOwner )) )
pObj->Lock();
}
inline SwCacheAccess::SwCacheAccess( SwCache &rC, const void *pOwn,
const USHORT nIndex ) :
rCache( rC ),
pObj( 0 ),
pOwner( pOwn )
2000-09-18 23:08:29 +00:00
{
if ( pOwner && 0 != (pObj = rCache.Get( pOwner, nIndex )) )
pObj->Lock();
}
inline SwCacheObj *SwCacheAccess::Get()
{
if ( !pObj )
_Get();
return pObj;
}
#endif