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, only different to m_pRealFirst when SetLRUOfst has been called
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
, OString aNm
);
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 /// Mark some entries as "do not delete"
110 /// @param nOfst determines how many are not to be touched
111 void SetLRUOfst( const sal_uInt16 nOfst
);
112 void ResetLRUOfst() { m_pFirst
= m_pRealFirst
; }
114 void IncreaseMax( const sal_uInt16 nAdd
);
115 void DecreaseMax( const sal_uInt16 nSub
);
116 sal_uInt16
GetCurMax() const { return m_nCurMax
; }
117 SwCacheObj
*First() { return m_pRealFirst
; }
118 static inline SwCacheObj
*Next( SwCacheObj
*pCacheObj
);
119 SwCacheObj
* operator[](sal_uInt16 nIndex
) { return m_aCacheObjects
[nIndex
].get(); }
120 sal_uInt16
size() { return m_aCacheObjects
.size(); }
123 /// Try to prevent visible SwParaPortions from being deleted.
124 class SwSaveSetLRUOfst
132 * The Cache object base class
133 * Users of the Cache must derive a class from the SwCacheObj and store
134 * their payload there
138 friend class SwCache
; /// Can do everything
140 SwCacheObj
*m_pNext
; /// For the LRU chaining
143 sal_uInt16 m_nCachePos
; /// Position in the Cache array
147 SwCacheObj
*GetNext() { return m_pNext
; }
148 SwCacheObj
*GetPrev() { return m_pPrev
; }
149 void SetNext( SwCacheObj
*pNew
) { m_pNext
= pNew
; }
150 void SetPrev( SwCacheObj
*pNew
) { m_pPrev
= pNew
; }
152 void SetCachePos(const sal_uInt16 nNew
)
154 if (m_nCachePos
!= nNew
)
160 virtual void UpdateCachePos() { }
163 const void *m_pOwner
;
167 SwCacheObj( const void *pOwner
);
168 virtual ~SwCacheObj();
170 const void *GetOwner() const { return m_pOwner
; }
171 inline bool IsOwner( const void *pNew
) const;
173 sal_uInt16
GetCachePos() const { return m_nCachePos
; }
175 bool IsLocked() const { return 0 != m_nLock
; }
181 void Lock() { ++m_nLock
; }
182 void Unlock() { --m_nLock
; }
187 * Access class for the Cache
189 * The Cache object is created in the ctor.
190 * If the Cache does not return one, the member is set to 0 and one is
191 * created on the Get() and added to the Cache (if possible).
192 * Cache users must derive a class from SwCacheAccess in order to
193 * guarantee type safety. The base class should always be called for the
194 * Get(). A derived Get() should only ever guarantee type safety.
195 * Cache objects are always locked for the instance's life time.
201 void Get_(bool isDuplicateOwnerAllowed
);
205 const void *m_pOwner
; /// Can be use in NewObj
207 virtual SwCacheObj
*NewObj() = 0;
209 inline SwCacheObj
*Get(bool isDuplicateOwnerAllowed
);
211 inline SwCacheAccess( SwCache
&rCache
, const void *pOwner
, bool bSeek
);
212 inline SwCacheAccess( SwCache
&rCache
, const void* nCacheId
, const sal_uInt16 nIndex
);
215 virtual ~SwCacheAccess();
219 inline bool SwCacheObj::IsOwner( const void *pNew
) const
221 return m_pOwner
&& m_pOwner
== pNew
;
224 inline SwCacheObj
*SwCache::Next( SwCacheObj
*pCacheObj
)
227 return pCacheObj
->GetNext();
232 inline SwCacheAccess::SwCacheAccess( SwCache
&rC
, const void *pOwn
, bool bSeek
) :
237 if ( bSeek
&& m_pOwner
)
239 m_pObj
= m_rCache
.Get( m_pOwner
);
245 inline SwCacheAccess::SwCacheAccess( SwCache
&rC
, const void* nCacheId
,
246 const sal_uInt16 nIndex
) :
253 m_pObj
= m_rCache
.Get( m_pOwner
, nIndex
);
259 inline SwCacheObj
*SwCacheAccess::Get(bool const isDuplicateOwnerAllowed
= true)
262 Get_(isDuplicateOwnerAllowed
);
268 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */