1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #ifndef INCLUDED_SW_SOURCE_CORE_INC_SWCACHE_HXX
20 #define INCLUDED_SW_SOURCE_CORE_INC_SWCACHE_HXX
23 * Here, we manage pointers in a simple PtrArray to objects.
24 * These objects are created (using new) in cache access classes; they are
25 * destroyed by the cache.
27 * One can access these objects by array index or by searching in the array.
28 * If you access it by index, managing the index is the responsibility of
31 * The cached objects are derived from the base class SwCacheObj.
32 * In it, the cache objects are doubly-linked which allows for the use of
35 * The LRU algorithm can be changed in the base class, by setting a virtual
36 * First Pointer. It can be set to the first real one plus an offset.
37 * By doing so we can protect the start area of the cache and make sure we
38 * don't mess up the cache during some special operations.
39 * E.g.: the Idle Handler should not destroy the cache for the visible area.
41 * The cache can be grown and shrunk in size.
42 * E.g.: The cache for FormatInfo is grown for every new Shell and shrunk
43 * when destroying them.
49 #include <rtl/string.hxx>
50 #include <tools/long.hxx>
56 std::vector
<std::unique_ptr
<SwCacheObj
>> m_aCacheObjects
;
57 std::vector
<sal_uInt16
> m_aFreePositions
; /// Free positions for the Insert if the maximum has not been reached
58 /// Every time an object is deregistered, its position is added here
59 SwCacheObj
*m_pRealFirst
; /// _ALWAYS_ the real first LRU
60 SwCacheObj
*m_pFirst
; /// The virtual first
63 sal_uInt16 m_nCurMax
; // Maximum of accepted objects
65 void DeleteObj( SwCacheObj
*pObj
);
69 tools::Long m_nAppend
; /// number of entries appended
70 tools::Long m_nInsertFree
; /// number of entries inserted on freed position
71 tools::Long m_nReplace
; /// number of LRU replacements
72 tools::Long m_nGetSuccess
;
73 tools::Long m_nGetFail
;
74 tools::Long m_nToTop
; /// number of reordering (LRU)
75 tools::Long m_nDelete
; /// number of explicit deletes
76 tools::Long m_nGetSeek
; /// number of gets without index
77 tools::Long m_nAverageSeekCnt
; /// number of seeks for all gets without index
78 tools::Long m_nFlushCnt
; /// number of flush calls
79 tools::Long m_nFlushedObjects
;
80 tools::Long m_nIncreaseMax
; /// number of cache size increases
81 tools::Long m_nDecreaseMax
; /// number of cache size decreases
88 // Only add sal_uInt8!!!
90 SwCache( const sal_uInt16 nInitSize
, const OString
&rNm
);
92 SwCache( const sal_uInt16 nInitSize
);
94 /// The dtor will free all objects still in the vector
99 //bToTop == false -> No LRU resorting!
100 SwCacheObj
*Get( const void *pOwner
, const bool bToTop
= true );
101 SwCacheObj
*Get( const void *pOwner
, const sal_uInt16 nIndex
,
102 const bool bToTop
= true );
103 void ToTop( SwCacheObj
*pObj
);
105 bool Insert(SwCacheObj
*pNew
, bool isDuplicateOwnerAllowed
);
106 void Delete(const void * pOwner
, sal_uInt16 nIndex
);
107 void Delete( const void *pOwner
);
109 void SetLRUOfst( const sal_uInt16 nOfst
); /// nOfst determines how many are not to be touched
110 void ResetLRUOfst() { m_pFirst
= m_pRealFirst
; }
112 void IncreaseMax( const sal_uInt16 nAdd
);
113 void DecreaseMax( const sal_uInt16 nSub
);
114 sal_uInt16
GetCurMax() const { return m_nCurMax
; }
115 SwCacheObj
*First() { return m_pRealFirst
; }
116 static inline SwCacheObj
*Next( SwCacheObj
*pCacheObj
);
117 SwCacheObj
* operator[](sal_uInt16 nIndex
) { return m_aCacheObjects
[nIndex
].get(); }
118 sal_uInt16
size() { return m_aCacheObjects
.size(); }
121 /// Try to prevent visible SwParaPortions from being deleted.
122 class SwSaveSetLRUOfst
130 * The Cache object base class
131 * Users of the Cache must derive a class from the SwCacheObj and store
132 * their payload there
136 friend class SwCache
; /// Can do everything
138 SwCacheObj
*m_pNext
; /// For the LRU chaining
141 sal_uInt16 m_nCachePos
; /// Position in the Cache array
145 SwCacheObj
*GetNext() { return m_pNext
; }
146 SwCacheObj
*GetPrev() { return m_pPrev
; }
147 void SetNext( SwCacheObj
*pNew
) { m_pNext
= pNew
; }
148 void SetPrev( SwCacheObj
*pNew
) { m_pPrev
= pNew
; }
150 void SetCachePos(const sal_uInt16 nNew
)
152 if (m_nCachePos
!= nNew
)
158 virtual void UpdateCachePos() { }
161 const void *m_pOwner
;
165 SwCacheObj( const void *pOwner
);
166 virtual ~SwCacheObj();
168 const void *GetOwner() const { return m_pOwner
; }
169 inline bool IsOwner( const void *pNew
) const;
171 sal_uInt16
GetCachePos() const { return m_nCachePos
; }
173 bool IsLocked() const { return 0 != m_nLock
; }
179 void Lock() { ++m_nLock
; }
180 void Unlock() { --m_nLock
; }
185 * Access class for the Cache
187 * The Cache object is created in the ctor.
188 * If the Cache does not return one, the member is set to 0 and one is
189 * created on the Get() and added to the Cache (if possible).
190 * Cache users must derive a class from SwCacheAccess in order to
191 * guarantee type safety. The base class should always be called for the
192 * Get(). A derived Get() should only ever guarantee type safety.
193 * Cache objects are always locked for the instance's life time.
199 void Get_(bool isDuplicateOwnerAllowed
);
203 const void *m_pOwner
; /// Can be use in NewObj
205 virtual SwCacheObj
*NewObj() = 0;
207 inline SwCacheObj
*Get(bool isDuplicateOwnerAllowed
);
209 inline SwCacheAccess( SwCache
&rCache
, const void *pOwner
, bool bSeek
);
210 inline SwCacheAccess( SwCache
&rCache
, const void* nCacheId
, const sal_uInt16 nIndex
);
213 virtual ~SwCacheAccess();
217 inline bool SwCacheObj::IsOwner( const void *pNew
) const
219 return m_pOwner
&& m_pOwner
== pNew
;
222 inline SwCacheObj
*SwCache::Next( SwCacheObj
*pCacheObj
)
225 return pCacheObj
->GetNext();
230 inline SwCacheAccess::SwCacheAccess( SwCache
&rC
, const void *pOwn
, bool bSeek
) :
235 if ( bSeek
&& m_pOwner
)
237 m_pObj
= m_rCache
.Get( m_pOwner
);
243 inline SwCacheAccess::SwCacheAccess( SwCache
&rC
, const void* nCacheId
,
244 const sal_uInt16 nIndex
) :
251 m_pObj
= m_rCache
.Get( m_pOwner
, nIndex
);
257 inline SwCacheObj
*SwCacheAccess::Get(bool const isDuplicateOwnerAllowed
= true)
260 Get_(isDuplicateOwnerAllowed
);
266 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */