2000-09-18 23:08:29 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2008-04-10 13:28:30 +00:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2008-04-10 13:28:30 +00:00
|
|
|
* Copyright 2008 by Sun Microsystems, Inc.
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2008-04-10 13:28:30 +00:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2008-04-10 13:28:30 +00:00
|
|
|
* $RCSfile: swcache.hxx,v $
|
|
|
|
* $Revision: 1.6 $
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2008-04-10 13:28:30 +00:00
|
|
|
* This file is part of OpenOffice.org.
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2008-04-10 13:28:30 +00:00
|
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
* only, as published by the Free Software Foundation.
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2008-04-10 13:28:30 +00:00
|
|
|
* OpenOffice.org 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 version 3 for more details
|
|
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2008-04-10 13:28:30 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
|
|
* <http://www.openoffice.org/license.html>
|
|
|
|
* for a copy of the LGPLv3 License.
|
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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2009-07-10 14:03:42 +02:00
|
|
|
#ifdef DBG_UTIL
|
2000-09-18 23:08:29 +00:00
|
|
|
#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 );
|
|
|
|
|
2009-07-10 14:03:42 +02:00
|
|
|
#ifdef DBG_UTIL
|
2000-09-18 23:08:29 +00:00
|
|
|
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!!!
|
2009-07-10 14:03:42 +02:00
|
|
|
#ifdef DBG_UTIL
|
2000-09-18 23:08:29 +00:00
|
|
|
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; }
|
|
|
|
|
2009-07-10 14:03:42 +02:00
|
|
|
#ifndef DBG_UTIL
|
2000-09-18 23:08:29 +00:00
|
|
|
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:
|
2004-06-16 08:39:35 +00:00
|
|
|
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 )
|
|
|
|
{
|
2007-09-27 07:58:37 +00:00
|
|
|
nCurMax = nCurMax + sal::static_int_cast< USHORT >(nAdd);
|
2009-07-10 14:03:42 +02:00
|
|
|
#ifdef DBG_UTIL
|
2000-09-18 23:08:29 +00:00
|
|
|
++nIncreaseMax;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
inline void SwCache::DecreaseMax( const USHORT nSub )
|
|
|
|
{
|
|
|
|
if ( nCurMax > nSub )
|
2007-09-27 07:58:37 +00:00
|
|
|
nCurMax = nCurMax - sal::static_int_cast< USHORT >(nSub);
|
2009-07-10 14:03:42 +02:00
|
|
|
#ifdef DBG_UTIL
|
2000-09-18 23:08:29 +00:00
|
|
|
++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 ),
|
2004-06-16 08:39:35 +00:00
|
|
|
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 ),
|
2004-06-16 08:39:35 +00:00
|
|
|
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
|