1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: swcache.hxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
36 * Es werden Pointer auf Objekte verwaltet. Diese werden in einem einfachen
38 * Angelegt (new) werden die Objekte von Cache-Zugriffsklassen, zuerstoert
39 * werden die Objekte vom Cache.
41 * Auf die Objekte kann wahlweise per Index in das Array oder per Suche
42 * zugegriffen werden. Soll per Index zugegriffen werden, so obliegt die
43 * Verwaltung des Index dem Anwender des Cache.
45 * Fuer die verwalteten Cache-Objekte gibt es eine Basisklasse, von dieser
46 * sind spezifische Klassen abzuleiten.
47 * In der Basisklasse werden die Cache-Objekte eines Cache doppelt verkettet,
48 * das ermoeglich die Implementierung eines LRU-Algorithmus.
50 * Der LRU kann in der Cache-Basisklasse manipuliert werden, indem ein
51 * virtueller First-Pointer gesetzt wird. Dieser kann auf den echten ersten
52 * plus einem Ofst gesetzt werden. Dadurch kann man den Anfangsbereich des
53 * Cache sichern und so dafuer sorgen, dass man waehrend bestimmter
54 * Operationen nicht den Cache versaut. Beispiel: Der Idle-Handler sollte nicht
55 * den Cache fuer den sichtbaren Bereich vernichten.
57 * Der Cache kann in der Groesse erweitert und wieder verkleinert werden.
58 * Beispiel: Fuer jede neue Shell wird der Cache fuer FormatInfo vergrossert
59 * und beim Destruieren der Shell wieder verkleinert.
64 #ifndef _STRING_HXX //autogen
65 #include <tools/string.hxx>
70 #define _SVSTDARR_USHORTS
71 #include <svtools/svstdarr.hxx>
76 SV_DECL_PTRARR_DEL(SwCacheObjArr
,SwCacheObj
*,1,1)
78 class SwCache
: public SwCacheObjArr
80 SvUShorts aFreePositions
; //Freie Positionen fuer das Insert wenn
81 //die Maximalgrenze nicht erreicht ist.
82 //Immer wenn ein Objekt ausgetragen wird,
83 //so wird seine Position hier eingetragen.
85 SwCacheObj
*pRealFirst
; //_immer_ der echte LRU-erste
86 SwCacheObj
*pFirst
; //der virtuelle erste.
89 const USHORT nMax
; //Mehr sollen nicht aufgenommen werden,
90 //der Cache kann aber dynamisch um jeweils
91 //nMax vergroessert werden.
92 USHORT nCurMax
; //Mehr werden nicht aufgenommen.
95 void DeleteObj( SwCacheObj
*pObj
);
99 long nAppend
; //Anzahl der Eintragungen durch Erweiterung.
100 long nInsertFree
; //Anzahl der Eintragungen auf freie Plaetze.
101 long nReplace
; //Anzahl der Ersetzungen durch ein neues Objekt
102 long nGetSuccess
; //Anzahl der Erfolgreichen Get's
103 long nGetFail
; //Anzahl der nicht Erfolgreichen Get's
104 long nToTop
; //Anzahl der Umsortierungen (LRU)
105 long nDelete
; //Anzahl der Loeschungen (von Aussen)
106 long nGetSeek
; //Anzahl der Get's ohne Index
107 long nAverageSeekCnt
; //Anzahl der Seek's fuer alle Get's ohne Index
108 long nFlushCnt
; //Anzahl von Flush-Aufrufen.
109 long nFlushedObjects
; //Anzahl der wg. Flush vernichteten Objekte
110 long nIncreaseMax
; //Anzahl Cache-Erweiterungen
111 long nDecreaseMax
; //Anzahl Cache-Verkleinerungen
113 void Check(); //Wird bei swcache.cxx mit DEBUG aktiv!
118 //nur BYTE hineinstecken!!!
120 SwCache( const USHORT nInitSize
, const USHORT nGrowSize
,
121 const ByteString
&rNm
);
124 SwCache( const USHORT nInitSize
, const USHORT nGrowSize
);
127 void Flush( const BYTE nPercent
= 100 );
129 //bToTop == FALSE -> Keine LRU-Umsortierung!
130 SwCacheObj
*Get( const void *pOwner
, const BOOL bToTop
= TRUE
);
131 SwCacheObj
*Get( const void *pOwner
, const USHORT nIndex
,
132 const BOOL bToTop
= TRUE
);
133 void ToTop( SwCacheObj
*pObj
);
135 BOOL
Insert( SwCacheObj
*pNew
);
136 void Delete( const void *pOwner
);
137 // void Delete( const void *pOwner, const USHORT nIndex );
139 void SetLRUOfst( const USHORT nOfst
); //nOfst sagt wieviele unangetastet
141 void ResetLRUOfst() { pFirst
= pRealFirst
; }
143 inline void IncreaseMax( const USHORT nAdd
);
144 inline void DecreaseMax( const USHORT nSub
);
145 USHORT
GetCurMax() const { return nCurMax
; }
146 inline SwCacheObj
*First() { return pRealFirst
; }
147 inline SwCacheObj
*Last() { return pLast
; }
148 inline SwCacheObj
*Next( SwCacheObj
*pCacheObj
);
151 //Cache-Manipulation auf die sichere Art.
152 class SwSaveSetLRUOfst
156 SwSaveSetLRUOfst( SwCache
&rC
, const USHORT nOfst
)
157 : rCache( rC
) { rCache
.SetLRUOfst( nOfst
); }
159 ~SwSaveSetLRUOfst() { rCache
.ResetLRUOfst(); }
162 //Das allgemeine CacheObjekt. Anwender des Cache muessen eine Klasse vom
163 //CacheObjekt ableiten und dort die Nutzdaten unterbringen.
167 friend class SwCache
; //Der darf alles
169 SwCacheObj
*pNext
; //Fuer die LRU-Verkettung.
172 USHORT nCachePos
; //Position im Cache-Array.
176 inline SwCacheObj
*GetNext() { return pNext
; }
177 inline SwCacheObj
*GetPrev() { return pPrev
; }
178 inline void SetNext( SwCacheObj
*pNew
) { pNext
= pNew
; }
179 inline void SetPrev( SwCacheObj
*pNew
) { pPrev
= pNew
; }
181 inline void SetCachePos( const USHORT nNew
) { nCachePos
= nNew
; }
185 inline void SetOwner( const void *pNew
) { pOwner
= pNew
; }
189 SwCacheObj( const void *pOwner
);
190 virtual ~SwCacheObj();
192 inline const void *GetOwner() const { return pOwner
; }
193 inline BOOL
IsOwner( const void *pNew
) const;
195 inline USHORT
GetCachePos() const { return nCachePos
; }
196 inline void Invalidate() { pOwner
= 0; }
198 inline BOOL
IsLocked() const { return 0 != nLock
; }
201 inline void Lock() { ++nLock
; }
202 inline void Unlock() { --nLock
; }
208 SwCacheObj
*Next() { return pNext
; }
209 SwCacheObj
*Prev() { return pPrev
; }
213 //Zugriffsklasse fuer den Cache. Im CTor wird das CacheObjekt erzeugt.
214 //Wenn der Cache keines herausrueckt wird der Member zunaechst auf 0 gesetzt.
215 //Beim Get wird dann eines erzeugt und, falls moeglich, in den Cache
217 //Anwender der des Cache muessen eine Klasse vom Access ableiten um
218 //fuer Typsicherheit zu sorgen, die Basisklasse sollte fuer das Get aber immer
219 //gerufen werden, ein Abgeleitetes Get sollte nur der Typsicherheit dienen.
220 //Cache-Objekte werden stets gelockt solange die Instanz lebt.
230 const void *pOwner
; //Kann ggf. in NewObj benutzt werden.
232 virtual SwCacheObj
*NewObj() = 0;
234 inline SwCacheObj
*Get();
236 inline SwCacheAccess( SwCache
&rCache
, const void *pOwner
, BOOL bSeek
= TRUE
);
237 inline SwCacheAccess( SwCache
&rCache
, const void *pOwner
, const USHORT nIndex
);
240 virtual ~SwCacheAccess();
242 virtual BOOL
IsAvailable() const;
244 //Abkuerzung fuer diejenigen, die wissen, das die Ableitung das IsAvailable
245 //nicht ueberladen haben.
246 BOOL
IsAvail() const { return pObj
!= 0; }
249 inline void SwCache::IncreaseMax( const USHORT nAdd
)
251 nCurMax
= nCurMax
+ sal::static_int_cast
< USHORT
>(nAdd
);
256 inline void SwCache::DecreaseMax( const USHORT nSub
)
258 if ( nCurMax
> nSub
)
259 nCurMax
= nCurMax
- sal::static_int_cast
< USHORT
>(nSub
);
265 inline BOOL
SwCacheObj::IsOwner( const void *pNew
) const
267 return pOwner
&& pOwner
== pNew
;
270 inline SwCacheObj
*SwCache::Next( SwCacheObj
*pCacheObj
)
273 return pCacheObj
->GetNext();
278 inline SwCacheAccess::SwCacheAccess( SwCache
&rC
, const void *pOwn
, BOOL bSeek
) :
283 if ( bSeek
&& pOwner
&& 0 != (pObj
= rCache
.Get( pOwner
)) )
287 inline SwCacheAccess::SwCacheAccess( SwCache
&rC
, const void *pOwn
,
288 const USHORT nIndex
) :
293 if ( pOwner
&& 0 != (pObj
= rCache
.Get( pOwner
, nIndex
)) )
297 inline SwCacheObj
*SwCacheAccess::Get()