summaryrefslogtreecommitdiff
path: root/sw/source/core/inc/swcache.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/inc/swcache.hxx')
-rw-r--r--sw/source/core/inc/swcache.hxx302
1 files changed, 302 insertions, 0 deletions
diff --git a/sw/source/core/inc/swcache.hxx b/sw/source/core/inc/swcache.hxx
new file mode 100644
index 000000000000..90803b515080
--- /dev/null
+++ b/sw/source/core/inc/swcache.hxx
@@ -0,0 +1,302 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * 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.
+ *
+ * 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).
+ *
+ * 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.
+ *
+ ************************************************************************/
+#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.
+ *
+ */
+
+#ifdef DBG_UTIL
+#ifndef _STRING_HXX //autogen
+#include <tools/string.hxx>
+#endif
+#endif
+
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_USHORTS
+#include <svl/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 );
+
+#ifdef DBG_UTIL
+ 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!!!
+#ifdef DBG_UTIL
+ 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; }
+
+#ifndef DBG_UTIL
+ 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();
+
+ 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);
+#ifdef DBG_UTIL
+ ++nIncreaseMax;
+#endif
+}
+inline void SwCache::DecreaseMax( const USHORT nSub )
+{
+ if ( nCurMax > nSub )
+ nCurMax = nCurMax - sal::static_int_cast< USHORT >(nSub);
+#ifdef DBG_UTIL
+ ++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 )
+{
+ 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 )
+{
+ if ( pOwner && 0 != (pObj = rCache.Get( pOwner, nIndex )) )
+ pObj->Lock();
+}
+
+inline SwCacheObj *SwCacheAccess::Get()
+{
+ if ( !pObj )
+ _Get();
+ return pObj;
+}
+
+
+#endif