ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
recycler.inl
Go to the documentation of this file.
1/** ************************************************************************************************
2 * \file
3 * This header file is part of module \alib_monomem of the \aliblong.
4 *
5 * \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6 * Published under \ref mainpage_license "Boost Software License".
7 **************************************************************************************************/
8#ifndef HPP_ALIB_MONOMEM_DETAIL_RECYCLER
9#define HPP_ALIB_MONOMEM_DETAIL_RECYCLER 1
10#if !defined(HPP_ALIB_MONOMEM_DETAIL_HASHTABLEBASE) \
11 && !defined(HPP_ALIB_MONOMEM_LIST)
12# error "ALib sources with ending '.inl' must not be included from outside."
13#endif
14
15#if !defined(HPP_ALIB_LANG_TMP) && !defined(ALIB_DOX)
16# include "alib/lang/tmp.hpp"
17#endif
18
19
20#if !defined(HPP_ALIB_LANG_SIDILIST)
21# include "alib/lang/sidilist.hpp"
22#endif
23
24#if ALIB_DEBUG
25# if !defined(HPP_ALIB_LANG_DBGTYPEDEMANGLER)
27# endif
28# if ALIB_STRINGS && !defined (HPP_ALIB_STRINGS_LOCALSTRING)
30# endif
31#endif
32
33#if !defined (_GLIBCXX_VECTOR) && !defined(_VECTOR_)
34# include <vector>
35#endif
36
37#if !defined (_GLIBCXX_MEMORY) && !defined(_MEMORY_)
38# include <memory>
39#endif
40
41
42namespace alib { namespace monomem { namespace detail {
43
44#if ALIB_DEBUG_MONOMEM && !defined(ALIB_DOX)
45 void dbgMonoMemRecyclingOutput(size_t a, size_t b, size_t c, const std::type_info& typeInfo, size_t d );
46#endif
47
48/** ************************************************************************************************
49 * This struct is used for recycling of "node elements" which are derived of type
50 * \alib{lang::SidiNodeBase}.
51 * This class provides the common base for \alib{monomem;detail::RecyclerPrivate} and
52 * \alib{monomem;detail::RecyclerShared}.
53 *
54 * @tparam TSidiNode The type to recycle. Has to be derived of \alib{lang::SidiNodeBase}.
55 * @tparam TList The type of the list of recyclables: Either the same as \p{TSidiNode}
56 * or a reference to it.
57 **************************************************************************************************/
58template<typename TSidiNode, typename TList >
60{
61 protected:
62 /** The list of recyclables. */
64
65 public:
66
67 /** Empty constructor, used by derived type \alib{monomem;detail::RecyclerPrivate}. */
68 RecyclerPSBase() = default;
69
70
71 /** Empty constructor, used by derived type \alib{monomem;detail::RecyclerShared}.
72 * @param sharedRecyclables The external list of recyclables. */
73 RecyclerPSBase( TList sharedRecyclables)
74 : recyclables( sharedRecyclables )
75 {}
76
77 /** Stores an element for recycling.
78 * @param elem The element to store. */
79 void recycle( TSidiNode* elem )
80 {
81 recyclables.pushFront( elem );
82 }
83
84 /** Stores a list of elements for recycling.
85 * @param first The first element of the list store.
86 * @param last The last element of the list store. */
87 void recycle( TSidiNode* first, TSidiNode* last )
88 {
89 recyclables.pushFront( first, last );
90 }
91
92 /** Recycles a chunk of memory that is \e not of the node type.
93 * Such recycling is useful for example, in combination with hash tables, which usually
94 * allocate a "bucket array" that grows over time. In this case, the former smaller bucket
95 * array may be passed to this method to recycle it as future node elements.
96 * @tparam TChunk The type of the chunk.
97 * @param chunk The recyclable chunk's address.
98 * @param count The number of objects (\c 1 for non-array types, <c>>1</c> for arrays. */
99 template<typename TChunk>
100 void recycleChunk( TChunk* chunk, size_t count )
101 {
102 void* mem = chunk;
103 size_t size= sizeof(TChunk[1]) * count;
104
105 // align beginning of buffer (if necessary)
106 if constexpr( alignof(TSidiNode) > alignof(TChunk[1]) )
107 std::align( alignof(TSidiNode) , // alignment: the desired alignment
108 sizeof (TSidiNode) , // size : the size of the storage to be aligned
109 mem , // ptr : pointer to contiguous storage of at least 'space' bytes
110 size ); // space : the size of the buffer in which to operate
111
112 // create recyclables
113 ALIB_DBG( size_t cntRecycledObjects= 0; )
114 while(size > sizeof(TSidiNode))
115 {
116 recyclables.pushFront( reinterpret_cast<TSidiNode*>( mem ) );
118 mem = reinterpret_cast<char*>(mem) + sizeof(TSidiNode);
119 size -= sizeof (TSidiNode);
120 ALIB_DBG( ++cntRecycledObjects; )
122 }
123
124 #if ALIB_DEBUG
125 if( cntRecycledObjects <= 0 )
126 {
127 #if ALIB_STRINGS
128 ALIB_WARNING( "MONOMEM/RECYCLER", NString4K() <<
129 "De-allocated chunk size is smaller than node size.\n"
130 " Chunk object: Type: <" << lang::DbgTypeDemangler( typeid(TChunk) ).Get() << ">\n"
131 " Size, Count, Alignment: " << sizeof(TChunk[1]) << " * " << count << " = "
132 << (sizeof(TChunk[1]) * count) << " bytes, alignment: "
133 << alignof(TChunk[1]) << "\n"
134 " Recyclable Type: <" << lang::DbgTypeDemangler( typeid(TSidiNode) ).Get() << ">\n"
135 " Size, Alignment: " << sizeof(TSidiNode) << " bytes, alignment: " << alignof(TSidiNode) << "\n"
136 "Note: If this recycler is used with a <monomem::HashTable>, this message may be eliminated\n"
137 " by reserving a reasonable initial bucket size." )
138 #else
139 ALIB_WARNING( cntRecycledObjects > 0, "MONOMEM/RECYCLER",
140 "De-allocated chunk size is smaller than node size." )
141 #endif
142 }
143 #endif
144
145 #if ALIB_DEBUG_MONOMEM
146 dbgMonoMemRecyclingOutput(
147 cntRecycledObjects,
148 sizeof(TChunk[1]) * count,
149 sizeof(TChunk[1]) * count - sizeof(TSidiNode) * cntRecycledObjects,
150 typeid(TChunk), count );
151 #endif
152 }
153
154 /** Returns a stored element. If no elements are available, \c nullptr is returned.
155 * @return A recycled element or \c nullptr if no recyclables are available. */
156 TSidiNode* get()
157 {
158 return recyclables.popFront();
159 }
160
161 /** Counts the number of recyclables.<br>
162 * Attention: This method runs in linear time.
163 * @return The number of available elements. */
165 {
166 return recyclables.count();
167 }
168
169}; // struct RecyclerPSBase
170
171/** ************************************************************************************************
172 * Implements internal recycling interface. Used by container types of module \alib_monomem_nl that
173 * use private recycling (when \b their template parameter \p{TRecycling} evaluates to
174 * \alib{monomem;Recycling::Private}).
175 *
176 * @tparam TSidiNode The type to recycle. Has to be derived of \alib{lang::SidiNodeBase}.
177 **************************************************************************************************/
178template<typename TSidiNode>
179struct RecyclerPrivate : RecyclerPSBase<TSidiNode, lang::SidiListHelper<TSidiNode>>
180{
181 /** Empty constructor, selected when \p{TRecycling} equals
182 * to \alib{monomem;Recycling::Private}. */
184 : RecyclerPSBase<TSidiNode, lang::SidiListHelper<TSidiNode>>()
185 {}
186
187 /** Copy constructor. Does not copy the recycle node, but clears this one. */
189 : RecyclerPSBase<TSidiNode, lang::SidiListHelper<TSidiNode>>()
190 {}
191
192 /** Move constructor. Grabs the recyclables from the moved one and sets moved to nulled.
193 * @param move The private recycler to move. */
195 : RecyclerPSBase<TSidiNode, lang::SidiListHelper<TSidiNode>>( move.recyclables )
196 {
197 move.recyclables.reset();
198 }
199
200 /** As the method name indicates, this implementation disposes the recyclables.
201 * This method is invoked by \b Reset() methods of containers which indicate that
202 * the monotonic memory is about to be reset likewise. */
207};
208
209/** ************************************************************************************************
210 * Implements internal recycling interface. Used by container types of module \alib_monomem_nl that
211 * use shared recycling (when \b their template parameter \p{TRecycling} evaluates to
212 * \alib{monomem;Recycling::Shared}).
213 *
214 * @tparam TSidiNode The type to recycle. Has to be derived of \alib{lang::SidiNodeBase}.
215 **************************************************************************************************/
216template<typename TSidiNode>
217struct RecyclerShared : RecyclerPSBase<TSidiNode, lang::SidiListHelper<TSidiNode>&>
218{
219 /** Constructor, selected when \p{TRecycling} equals
220 * to \alib{monomem;Recycling::Shared}.
221 * @param sharedRecyclables The external list of recyclables. */
223 : RecyclerPSBase<TSidiNode, lang::SidiListHelper<TSidiNode>&>( sharedRecyclables )
224 {}
225
226 /** Copy constructor. Copies the reference to the shared recycler.
227 * @param copy The private recycler to copy. */
229 : RecyclerPSBase<TSidiNode, lang::SidiListHelper<TSidiNode>&>( copy )
230 {}
231
232 /** Move constructor. Just copies the reference but leaves original intact. (We don't care)
233 * @param move The private recycler to move. */
235 : RecyclerPSBase<TSidiNode, lang::SidiListHelper<TSidiNode>&>( move )
236 {}
237
238 /** As the method name indicates, this implementation is empty.
239 * This method is invoked by \b Reset() methods of containers which indicate that
240 * the monotonic memory is about to be reset likewise. */
243};
244
245
246/** ************************************************************************************************
247 * Implements internal recycling interface. Used by container types of module \alib_monomem_nl that
248 * omit recycling (when \b their template parameter \p{TRecycling} evaluates to
249 * \alib{monomem;Recycling::None}).
250 *
251 * \note
252 * The interface of this type is not documented, as all methods are emtpy, or return
253 * <c>constexpr 0</c>.<br>
254 * \see
255 * Non-empty 'implementations' of this template type are given with
256 * \alib{monomem;detail::RecyclerPrivate} and \alib{monomem;detail::RecyclerShared}.
257 *
258 * @tparam TSidiNode The type to recycle. Has to be derived of \alib{lang::SidiNodeBase}.
259 **************************************************************************************************/
260template<typename TSidiNode>
262{
263#if !defined(ALIB_DOX)
264 constexpr RecyclerVoid() {}
265 void recycle( TSidiNode* ) const {}
266 void recycle( TSidiNode* , TSidiNode* ) const {}
267 constexpr TSidiNode* get() const { return nullptr; }
268 constexpr integer count() const { return 0; }
269 void disposeRecyclablesIfPrivate() const {}
270 template<typename TChunk>
271 void recycleChunk( TChunk*, size_t ) const {}
272#endif
273
274}; // struct RecyclerVoid
275
276
277}} // namespace alib[::monomem::detail]
278
279} // namespace [alib]
280
281#endif // HPP_ALIB_MONOMEM_DETAIL_RECYCLER
#define ALIB_WARNING(...)
Definition alib.hpp:981
#define ALIB_WARNINGS_RESTORE
Definition alib.hpp:715
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
Definition alib.hpp:644
#define ALIB_DBG(...)
Definition alib.hpp:457
Definition alib.cpp:57
NLocalString< 4096 > NString4K
Type alias name for TLocalString<nchar,4096> .
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286
RecyclerPSBase(TList sharedRecyclables)
Definition recycler.inl:73
void recycle(TSidiNode *first, TSidiNode *last)
Definition recycler.inl:87
void recycleChunk(TChunk *chunk, size_t count)
Definition recycler.inl:100
RecyclerPrivate(const RecyclerPrivate &)
Definition recycler.inl:188
RecyclerPrivate(RecyclerPrivate &&move)
Definition recycler.inl:194
RecyclerShared(lang::SidiListHelper< TSidiNode > &sharedRecyclables)
Definition recycler.inl:222
RecyclerShared(const RecyclerShared &copy)
Definition recycler.inl:228
RecyclerShared(RecyclerShared &&move)
Definition recycler.inl:234