1 A simplistic mem free list implementation using vector
3 From: Thorsten Behrens <thb@openoffice.org>
8 o3tl/inc/o3tl/vector_pool.hxx | 132 +++++++++++++++++++++++++++++++++++++++++
9 o3tl/qa/makefile.mk | 1
10 o3tl/qa/test-vector_pool.cxx | 73 +++++++++++++++++++++++
11 3 files changed, 206 insertions(+), 0 deletions(-)
12 create mode 100644 o3tl/inc/o3tl/vector_pool.hxx
13 create mode 100644 o3tl/qa/test-vector_pool.cxx
16 diff --git o3tl/inc/o3tl/vector_pool.hxx o3tl/inc/o3tl/vector_pool.hxx
18 index 0000000..9f80e3b
20 +++ o3tl/inc/o3tl/vector_pool.hxx
22 +/*************************************************************************
24 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
26 + * Copyright 2008 by Sun Microsystems, Inc.
28 + * OpenOffice.org - a multi-platform office productivity suite
30 + * $RCSfile: lazy_update.hxx,v $
33 + * This file is part of OpenOffice.org.
35 + * OpenOffice.org is free software: you can redistribute it and/or modify
36 + * it under the terms of the GNU Lesser General Public License version 3
37 + * only, as published by the Free Software Foundation.
39 + * OpenOffice.org is distributed in the hope that it will be useful,
40 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
41 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42 + * GNU Lesser General Public License version 3 for more details
43 + * (a copy is included in the LICENSE file that accompanied this code).
45 + * You should have received a copy of the GNU Lesser General Public License
46 + * version 3 along with OpenOffice.org. If not, see
47 + * <http://www.openoffice.org/license.html>
48 + * for a copy of the LGPLv3 License.
50 + ************************************************************************/
52 +#ifndef INCLUDED_O3TL_VECTOR_POOL_HXX
53 +#define INCLUDED_O3TL_VECTOR_POOL_HXX
55 +#include <sal/types.h>
62 + template<typename ValueType, class Container> class simple_pool_impl :
65 + typedef typename Container::value_type value_type;
66 + std::ptrdiff_t mnFirstFreeIndex;
69 + simple_pool_impl() :
70 + mnFirstFreeIndex(-1)
73 + std::ptrdiff_t alloc()
75 + return store(ValueType());
78 + std::ptrdiff_t store(const ValueType& rCopy)
80 + if( mnFirstFreeIndex != -1 )
82 + std::ptrdiff_t nIdx=mnFirstFreeIndex;
83 + mnFirstFreeIndex = this->at(mnFirstFreeIndex).nextFree;
84 + this->at(nIdx).value = rCopy;
85 + this->at(nIdx).nextFree = -1;
91 + push_back(value_type(rCopy));
92 + return this->size()-1;
96 + void free( std::ptrdiff_t nIdx )
98 + this->at(nIdx).nextFree = mnFirstFreeIndex;
99 + mnFirstFreeIndex = nIdx;
102 + const ValueType& get( std::ptrdiff_t nIdx ) const
104 + return this->operator[](nIdx).value;
106 + ValueType& get( std::ptrdiff_t nIdx )
108 + return this->operator[](nIdx).value;
112 + template< typename ValueType > struct struct_from_value
120 + explicit type( const ValueType& val ) :
126 + std::ptrdiff_t nextFree;
131 + /** Simple vector-based memory pool allocator
133 + This template can be used to provide simple pooled memory
134 + allocation from a container class that adheres to the stl
135 + random access container concept. Note that alloc/free works
136 + with _indices_ into the container!
140 +vector_pool<type> myPool;
141 +int nIdx=myPool.alloc();
142 +myPool[nIdx] = myVal;
147 + template<typename ValueType> struct vector_pool :
148 + public detail::simple_pool_impl<ValueType,
149 + std::vector<typename detail::struct_from_value<ValueType>::type > >
153 +#endif /* INCLUDED_O3TL_VECTOR_POOL_HXX */
154 diff --git o3tl/qa/makefile.mk o3tl/qa/makefile.mk
155 index 5a71a78..dd69222 100644
156 --- o3tl/qa/makefile.mk
157 +++ o3tl/qa/makefile.mk
158 @@ -46,6 +46,7 @@ ENABLE_EXCEPTIONS=TRUE
160 $(SLO)$/cow_wrapper_clients.obj \
161 $(SLO)$/test-cow_wrapper.obj \
162 + $(SLO)$/test-vector_pool.obj \
163 $(SLO)$/test-heap_ptr.obj \
164 $(SLO)$/test-range.obj
166 diff --git o3tl/qa/test-vector_pool.cxx o3tl/qa/test-vector_pool.cxx
168 index 0000000..46f188e
170 +++ o3tl/qa/test-vector_pool.cxx
172 +// autogenerated file with codegen.pl
174 +#include <cppunit/simpleheader.hxx>
176 +#include <o3tl/vector_pool.hxx>
178 +using namespace ::o3tl;
180 +class vector_pool_test : public CppUnit::TestFixture
183 + void testPoolBasics()
185 + vector_pool<int> aPool;
187 + std::ptrdiff_t nIdx1 = aPool.alloc();
188 + std::ptrdiff_t nIdx2 = aPool.alloc();
189 + std::ptrdiff_t nIdx3 = aPool.alloc();
191 + CPPUNIT_ASSERT_MESSAGE("allocator idx order 1", nIdx1 < nIdx2 );
192 + CPPUNIT_ASSERT_MESSAGE("allocator idx order 2", nIdx2 < nIdx3 );
197 + nIdx2 = aPool.alloc();
198 + nIdx3 = aPool.alloc();
200 + CPPUNIT_ASSERT_MESSAGE("allocator idx order 1 after fragmentation", nIdx1 < nIdx3 );
201 + CPPUNIT_ASSERT_MESSAGE("allocator idx order 2 after fragmentation", nIdx3 < nIdx2 );
204 + void testPoolValueSemantics()
206 + vector_pool<int> aPool;
208 + std::ptrdiff_t nIdx1 = aPool.store(0);
209 + CPPUNIT_ASSERT_MESSAGE("allocator value semantics 1", aPool.get(nIdx1) == 0 );
211 + std::ptrdiff_t nIdx2 = aPool.store(1);
212 + CPPUNIT_ASSERT_MESSAGE("allocator value semantics 2", aPool.get(nIdx2) == 1 );
214 + std::ptrdiff_t nIdx3 = aPool.store(2);
215 + CPPUNIT_ASSERT_MESSAGE("allocator value semantics 3", aPool.get(nIdx3) == 2 );
220 + nIdx2 = aPool.store(1);
221 + CPPUNIT_ASSERT_MESSAGE("allocator value semantics 2 after fragmentation", aPool.get(nIdx2) == 1 );
223 + nIdx3 = aPool.store(2);
224 + CPPUNIT_ASSERT_MESSAGE("allocator value semantics 3 after fragmentation", aPool.get(nIdx3) == 2 );
227 + // Change the following lines only, if you add, remove or rename
228 + // member functions of the current class,
229 + // because these macros are need by auto register mechanism.
231 + CPPUNIT_TEST_SUITE(vector_pool_test);
232 + CPPUNIT_TEST(testPoolBasics);
233 + CPPUNIT_TEST(testPoolValueSemantics);
234 + CPPUNIT_TEST_SUITE_END();
237 +// -----------------------------------------------------------------------------
238 +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(vector_pool_test, "vector pool test");
241 +// -----------------------------------------------------------------------------