Skip to content

Commit 975bdae

Browse files
committed
adding sources
0 parents  commit 975bdae

File tree

10 files changed

+2103
-0
lines changed

10 files changed

+2103
-0
lines changed

‎.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/Visual*
2+
/bin

‎CMakeLists.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
cmake_minimum_required(VERSION 2.4)
2+
project( shared_allocator_test )
3+
4+
set(ROOT
5+
${CMAKE_CURRENT_LIST_DIR}
6+
)
7+
8+
include_directories(
9+
${ROOT}/include
10+
)
11+
12+
set(OUTPUT_DIR
13+
${ROOT}/bin
14+
)
15+
16+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
17+
${OUTPUT_DIR}
18+
)
19+
20+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
21+
${OUTPUT_DIR}
22+
)
23+
24+
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
25+
${OUTPUT_DIR}
26+
)
27+
28+
if(UNIX)
29+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
30+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic" )
31+
else()
32+
add_definitions( -D_CRT_SECURE_NO_WARNINGS )
33+
endif(UNIX)
34+
35+
add_subdirectory(source)
36+
add_subdirectory(test)

‎LICENSE

Lines changed: 621 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
/***************************************************************************************
2+
* file : cached_allocator.hpp
3+
* data : 2016/03/05
4+
* author : Victor Zarubkin
5+
* contact : v.s.zarubkin@gmail.com
6+
* copyright : Copyright (C) 2016 Victor Zarubkin
7+
* :
8+
* description : This header contains definition of cached_allocator class which can be used to speed-up rapid allocations
9+
* : and deallocations of memory buffers of the same size. It is best to use this allocator to allocate and deallocate
10+
* : single instances of objects (memory buffers of size 1).
11+
* :
12+
* references : Original (and actual) version of source code can be found here <http://www.github.com/cas4ey/shared_allocator>.
13+
* :
14+
* license : This file is part of SharedAllocator.
15+
* :
16+
* : SharedAllocator is free software: you can redistribute it and/or modify
17+
* : it under the terms of the GNU General Public License as published by
18+
* : the Free Software Foundation, either version 3 of the License, or
19+
* : (at your option) any later version.
20+
* :
21+
* : SharedAllocator is distributed in the hope that it will be useful,
22+
* : but WITHOUT ANY WARRANTY; without even the implied warranty of
23+
* : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24+
* : GNU General Public License for more details.
25+
* :
26+
* : You should have received a copy of the GNU General Public License
27+
* : along with SharedAllocator. If not, see <http://www.gnu.org/licenses/>.
28+
* :
29+
* : A copy of the GNU General Public License can be found in file LICENSE.
30+
****************************************************************************************/
31+
32+
#ifndef SHARED___ALLOCATOR__SINGLE_CACHED_ALLOCATOR___HPP___
33+
#define SHARED___ALLOCATOR__SINGLE_CACHED_ALLOCATOR___HPP___
34+
35+
#include "shared_allocator/shared_allocator.hpp"
36+
#include <vector>
37+
38+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
39+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
40+
41+
namespace salloc {
42+
43+
/** \brief Allocator that caches memory for objects for further usage.
44+
45+
It caches deallocated memory buffers and uses them later to provide fast allocation of memory buffers of the SAME SIZE (or lesser size).
46+
47+
\note It is better to use this allocator to allocate memory buffers of the same size.
48+
49+
\note BEST TO USE IF YOU WANT TO ALLOCATE AND DEALLOCATE BUFFERS OF SIZE 1 (SINGLE INSTANCES OF OBJECTS)
50+
(Best fit for std::list, std::set, std::map BUT NOT for std::vector).
51+
52+
\ingroup salloc */
53+
template <class T, class TAlloc = shared_allocator<T> >
54+
class cached_allocator
55+
{
56+
protected:
57+
58+
template <class U>
59+
using TSameAlloc = typename TAlloc::template rebind<U>::other;
60+
61+
typedef ::std::vector<T*, TSameAlloc<T*> > MemoryCache;
62+
63+
MemoryCache m_memoryCache; ///< Memory cache of objects
64+
const TAlloc m_allocator; ///< Allocator to allocate new instances of T
65+
66+
public:
67+
68+
typedef T value_type;
69+
70+
typedef value_type* pointer;
71+
typedef const value_type* const_pointer;
72+
typedef void* void_pointer;
73+
typedef const void* const_void_pointer;
74+
75+
typedef value_type& reference;
76+
typedef const value_type& const_reference;
77+
78+
typedef size_t size_type;
79+
typedef ptrdiff_t difference_type;
80+
81+
/** \brief Auxiliary struct to convert this type to single_cached_allocator of other type. */
82+
template <class U>
83+
struct rebind
84+
{
85+
typedef cached_allocator<U> other;
86+
};
87+
88+
/** \brief Returns an actual adress of value.
89+
90+
\note Uses std::addressof */
91+
pointer address(reference _value) const throw()
92+
{
93+
return ::std::addressof(_value);
94+
}
95+
96+
/** \brief Returns an actual adress of const value.
97+
98+
\note Uses std::addressof */
99+
const_pointer address(const_reference _value) const throw()
100+
{
101+
return ::std::addressof(_value);
102+
}
103+
104+
/** \brief Default constructor.
105+
106+
Does nothing. */
107+
cached_allocator() throw()
108+
{
109+
}
110+
111+
/** \brief Empty copy constructor.
112+
113+
Does nothing. */
114+
template <class U>
115+
cached_allocator(const cached_allocator<U>&) throw()
116+
{
117+
}
118+
119+
/** \brief Move constructor.
120+
121+
Moves reserved memory. */
122+
cached_allocator(cached_allocator<T>&& _rvalueAlloc) : m_memoryCache(::std::move(_rvalueAlloc.m_memoryCache))
123+
{
124+
}
125+
126+
/** \brief Empty assignment operator.
127+
128+
Does nothing and returns reference to this allocator. */
129+
template <class U>
130+
cached_allocator<T>& operator=(const cached_allocator<U>&)
131+
{
132+
return *this;
133+
}
134+
135+
~cached_allocator()
136+
{
137+
for (auto pMem : m_memoryCache)
138+
{
139+
m_allocator.deallocate(pMem);
140+
}
141+
}
142+
143+
/** \brief Swaps two allocators with their cache.
144+
145+
\param _anotherAlloc Reference to another allocator. */
146+
void swap(cached_allocator<T>& _anotherAlloc)
147+
{
148+
m_memoryCache.swap(_anotherAlloc.m_memoryCache);
149+
}
150+
151+
/** \brief Reserve memory for certain number of elements.
152+
153+
Reserves memory for number of buffers of specified size.
154+
155+
\param _arraySize Required number of elements to reserve (size of one memory buffer).
156+
\param _reservationsNumber Required number of memory buffers. */
157+
void reserve(size_type _arraySize, size_type _reservationsNumber)
158+
{
159+
m_memoryCache.reserve(m_memoryCache.size() + _reservationsNumber);
160+
for (size_type i = 0; i < _reservationsNumber; ++i)
161+
{
162+
m_memoryCache.push_back(m_allocator.allocate(_arraySize));
163+
}
164+
}
165+
166+
/** \brief Returns number of elements in allocated memory.
167+
168+
\param _memory Pointer to allocated memory.
169+
170+
\warning Please, notice that the number of ELEMENTS will be returned (not number of BYTES).
171+
172+
\note This function made template to avoid compiler errors for allocators that do not have size() function. */
173+
template <class U>
174+
inline size_type size(const U* _memory) const
175+
{
176+
return m_allocator.size(_memory);
177+
}
178+
179+
/** \brief Stores pointer to memory in cache to be used later.
180+
181+
\param _memory Pointer to allocated memory. */
182+
void deallocate(pointer _memory, size_type = 0)
183+
{
184+
m_memoryCache.push_back(_memory);
185+
}
186+
187+
/** \brief Truly deallocates memory.
188+
189+
\param _memory Pointer to allocated memory. */
190+
inline void deallocate_force(pointer _memory, size_type = 0) const
191+
{
192+
m_allocator.deallocate(pMem);
193+
}
194+
195+
/** \brief Allocate elements.
196+
197+
\param _number Required number of elements. */
198+
pointer allocate(size_type _number = 1)
199+
{
200+
if (!m_memoryCache.empty())
201+
{
202+
pointer pMem = m_memoryCache.back();
203+
m_memoryCache.pop_back();
204+
return _number < 2 ? pMem : m_allocator.allocate(_number, pMem);
205+
}
206+
207+
return m_allocator.allocate(_number);
208+
}
209+
210+
/** \brief Allocate elements using hint.
211+
212+
\param _number Required number of elements.
213+
\param _currentMemory Pointer to memory allocated earlier (it contains size which will be used as a hint). */
214+
pointer allocate(size_type _number, void* _currentMemory) const
215+
{
216+
if (!m_memoryCache.empty())
217+
{
218+
pointer pMem = m_memoryCache.back();
219+
m_memoryCache.pop_back();
220+
return _number < 2 ? pMem : m_allocator.allocate(_number, pMem);
221+
}
222+
223+
return m_allocator.allocate(_number, _currentMemory);
224+
}
225+
226+
/** \brief Construct new object on preallocated memory using default constructor.
227+
228+
\param _singleObject Pointer to preallocated memory. */
229+
inline void construct(T* _singleObject) const
230+
{
231+
shared_construct(_singleObject);
232+
}
233+
234+
/** \brief Construct new object on preallocated memory using copy-constructor.
235+
236+
\param _singleObject Pointer to preallocated memory.
237+
\param _value Const-reference to another object instance to be coped from.
238+
239+
\note Declared as template function to make it possible to use this allocator with
240+
types without public copy-constructor. */
241+
template <class U>
242+
inline void construct(U* _singleObject, const U& _value) const
243+
{
244+
shared_construct(_singleObject, _value);
245+
}
246+
247+
/** \brief Construct new object on preallocated memory using move-constructor.
248+
249+
\param _singleObject Pointer to preallocated memory.
250+
\param _value Rvalue-reference to another object instance to be moved from.
251+
252+
\note Declared as template function to make it possible to use this allocator with
253+
types without public move-constructor. */
254+
template <class U>
255+
inline void construct(U* _singleObject, U&& _value) const
256+
{
257+
shared_construct(_singleObject, _value);
258+
}
259+
260+
/** \brief Construct new object on preallocated memory using arguments list.
261+
262+
\param _singleObject Pointer to preallocated memory.
263+
\param _constructorArguments Variadic arguments list to be used by object constructor.
264+
265+
\note Declared as template function to make it possible to use this allocator with
266+
types without specific constructor with arguments. */
267+
template <class U, class... TArgs>
268+
inline void construct(U* _singleObject, TArgs&&... _constructorArguments) const
269+
{
270+
::new (static_cast<void*>(_singleObject)) U(::std::forward<TArgs>(_constructorArguments)...);
271+
}
272+
273+
/** \brief Destroy pointed object.
274+
275+
Invokes object's destructor.
276+
277+
\param _singleObject Pointer to object.
278+
279+
\note Declared as template function to make it possible to use this allocator with
280+
types without public destructor. */
281+
template <class U>
282+
inline void destroy(U* _singleObject) const
283+
{
284+
_singleObject->~U();
285+
}
286+
287+
/** \brief Estimate maximum array size. */
288+
size_t max_size() const throw()
289+
{
290+
return (size_t)(-1) / sizeof(T);
291+
}
292+
293+
}; // END class single_cached_allocator<T>.
294+
295+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
296+
297+
// Using single_cached_allocator for itself is restricted.
298+
template <class T, class U>
299+
class cached_allocator<T, cached_allocator<U> >;
300+
301+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
302+
303+
template <class T>
304+
using local_cached_allocator = cached_allocator<T, std::allocator<T> >;
305+
306+
} // END namespace salloc.
307+
308+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
309+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
310+
311+
#endif // SHARED___ALLOCATOR__SINGLE_CACHED_ALLOCATOR___HPP___

0 commit comments

Comments
 (0)