summaryrefslogtreecommitdiffstats
path: root/bf_sw/source/core/inc/swcache.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'bf_sw/source/core/inc/swcache.hxx')
-rw-r--r--bf_sw/source/core/inc/swcache.hxx281
1 files changed, 281 insertions, 0 deletions
diff --git a/bf_sw/source/core/inc/swcache.hxx b/bf_sw/source/core/inc/swcache.hxx
new file mode 100644
index 000000000..b7dc37034
--- /dev/null
+++ b/bf_sw/source/core/inc/swcache.hxx
@@ -0,0 +1,281 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef _SWCACHE_HXX
+#define _SWCACHE_HXX
+
+#include <bf_svtools/bf_solar.h>
+
+
+
+
+/*
+ * 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
+#include <bf_tools/string.hxx>
+#endif
+
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_USHORTS
+#include <bf_svtools/svstdarr.hxx>
+#endif
+namespace binfilter {
+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
+
+ //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 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);
+};
+
+//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() { if ( pObj ) pObj->Unlock(); }
+
+
+ //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 += nAdd;
+#ifdef DBG_UTIL
+ ++nIncreaseMax;
+#endif
+}
+inline void SwCache::DecreaseMax( const USHORT nSub )
+{
+ if ( nCurMax > nSub )
+ nCurMax -= 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;
+}
+
+
+} //namespace binfilter
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */