#i105938# Provides simplistic pool memory from a std::vector
This commit is contained in:
132
o3tl/inc/o3tl/vector_pool.hxx
Normal file
132
o3tl/inc/o3tl/vector_pool.hxx
Normal file
@@ -0,0 +1,132 @@
|
||||
/*************************************************************************
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* Copyright 2008 by Sun Microsystems, Inc.
|
||||
*
|
||||
* OpenOffice.org - a multi-platform office productivity suite
|
||||
*
|
||||
* $RCSfile: lazy_update.hxx,v $
|
||||
* $Revision: 1.3 $
|
||||
*
|
||||
* This file is part of OpenOffice.org.
|
||||
*
|
||||
* OpenOffice.org is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version 3
|
||||
* only, as published by the Free Software Foundation.
|
||||
*
|
||||
* OpenOffice.org is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License version 3 for more details
|
||||
* (a copy is included in the LICENSE file that accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* version 3 along with OpenOffice.org. If not, see
|
||||
* <http://www.openoffice.org/license.html>
|
||||
* for a copy of the LGPLv3 License.
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#ifndef INCLUDED_O3TL_VECTOR_POOL_HXX
|
||||
#define INCLUDED_O3TL_VECTOR_POOL_HXX
|
||||
|
||||
#include <sal/types.h>
|
||||
#include <vector>
|
||||
|
||||
namespace o3tl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename ValueType, class Container> class simple_pool_impl :
|
||||
public Container
|
||||
{
|
||||
typedef typename Container::value_type value_type;
|
||||
std::ptrdiff_t mnFirstFreeIndex;
|
||||
|
||||
public:
|
||||
simple_pool_impl() :
|
||||
mnFirstFreeIndex(-1)
|
||||
{}
|
||||
|
||||
std::ptrdiff_t alloc()
|
||||
{
|
||||
return store(ValueType());
|
||||
}
|
||||
|
||||
std::ptrdiff_t store(const ValueType& rCopy)
|
||||
{
|
||||
if( mnFirstFreeIndex != -1 )
|
||||
{
|
||||
std::ptrdiff_t nIdx=mnFirstFreeIndex;
|
||||
mnFirstFreeIndex = this->at(mnFirstFreeIndex).nextFree;
|
||||
this->at(nIdx).value = rCopy;
|
||||
this->at(nIdx).nextFree = -1;
|
||||
|
||||
return nIdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
push_back(value_type(rCopy));
|
||||
return this->size()-1;
|
||||
}
|
||||
}
|
||||
|
||||
void free( std::ptrdiff_t nIdx )
|
||||
{
|
||||
this->at(nIdx).nextFree = mnFirstFreeIndex;
|
||||
mnFirstFreeIndex = nIdx;
|
||||
}
|
||||
|
||||
const ValueType& get( std::ptrdiff_t nIdx ) const
|
||||
{
|
||||
return this->operator[](nIdx).value;
|
||||
}
|
||||
ValueType& get( std::ptrdiff_t nIdx )
|
||||
{
|
||||
return this->operator[](nIdx).value;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename ValueType > struct struct_from_value
|
||||
{
|
||||
struct type
|
||||
{
|
||||
type() :
|
||||
value(),
|
||||
nextFree(-1)
|
||||
{}
|
||||
explicit type( const ValueType& val ) :
|
||||
value(val),
|
||||
nextFree(-1)
|
||||
{}
|
||||
|
||||
ValueType value;
|
||||
std::ptrdiff_t nextFree;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/** Simple vector-based memory pool allocator
|
||||
|
||||
This template can be used to provide simple pooled memory
|
||||
allocation from a container class that adheres to the stl
|
||||
random access container concept. Note that alloc/free works
|
||||
with _indices_ into the container!
|
||||
|
||||
@example
|
||||
<pre>
|
||||
vector_pool<type> myPool;
|
||||
int nIdx=myPool.alloc();
|
||||
myPool[nIdx] = myVal;
|
||||
... do stuff ...
|
||||
myPool.free(nIdx);
|
||||
</pre>
|
||||
*/
|
||||
template<typename ValueType> struct vector_pool :
|
||||
public detail::simple_pool_impl<ValueType,
|
||||
std::vector<typename detail::struct_from_value<ValueType>::type > >
|
||||
{};
|
||||
}
|
||||
|
||||
#endif /* INCLUDED_O3TL_VECTOR_POOL_HXX */
|
@@ -46,6 +46,7 @@ ENABLE_EXCEPTIONS=TRUE
|
||||
SHL1OBJS= \
|
||||
$(SLO)$/cow_wrapper_clients.obj \
|
||||
$(SLO)$/test-cow_wrapper.obj \
|
||||
$(SLO)$/test-vector_pool.obj \
|
||||
$(SLO)$/test-heap_ptr.obj \
|
||||
$(SLO)$/test-range.obj
|
||||
|
||||
|
73
o3tl/qa/test-vector_pool.cxx
Normal file
73
o3tl/qa/test-vector_pool.cxx
Normal file
@@ -0,0 +1,73 @@
|
||||
// autogenerated file with codegen.pl
|
||||
|
||||
#include <cppunit/simpleheader.hxx>
|
||||
|
||||
#include <o3tl/vector_pool.hxx>
|
||||
|
||||
using namespace ::o3tl;
|
||||
|
||||
class vector_pool_test : public CppUnit::TestFixture
|
||||
{
|
||||
public:
|
||||
void testPoolBasics()
|
||||
{
|
||||
vector_pool<int> aPool;
|
||||
|
||||
std::ptrdiff_t nIdx1 = aPool.alloc();
|
||||
std::ptrdiff_t nIdx2 = aPool.alloc();
|
||||
std::ptrdiff_t nIdx3 = aPool.alloc();
|
||||
|
||||
CPPUNIT_ASSERT_MESSAGE("allocator idx order 1", nIdx1 < nIdx2 );
|
||||
CPPUNIT_ASSERT_MESSAGE("allocator idx order 2", nIdx2 < nIdx3 );
|
||||
|
||||
aPool.free(nIdx2);
|
||||
aPool.free(nIdx3);
|
||||
|
||||
nIdx2 = aPool.alloc();
|
||||
nIdx3 = aPool.alloc();
|
||||
|
||||
CPPUNIT_ASSERT_MESSAGE("allocator idx order 1 after fragmentation", nIdx1 < nIdx3 );
|
||||
CPPUNIT_ASSERT_MESSAGE("allocator idx order 2 after fragmentation", nIdx3 < nIdx2 );
|
||||
}
|
||||
|
||||
void testPoolValueSemantics()
|
||||
{
|
||||
vector_pool<int> aPool;
|
||||
|
||||
std::ptrdiff_t nIdx1 = aPool.store(0);
|
||||
CPPUNIT_ASSERT_MESSAGE("allocator value semantics 1", aPool.get(nIdx1) == 0 );
|
||||
|
||||
std::ptrdiff_t nIdx2 = aPool.store(1);
|
||||
CPPUNIT_ASSERT_MESSAGE("allocator value semantics 2", aPool.get(nIdx2) == 1 );
|
||||
|
||||
std::ptrdiff_t nIdx3 = aPool.store(2);
|
||||
CPPUNIT_ASSERT_MESSAGE("allocator value semantics 3", aPool.get(nIdx3) == 2 );
|
||||
|
||||
aPool.free(nIdx2);
|
||||
aPool.free(nIdx3);
|
||||
|
||||
nIdx2 = aPool.store(1);
|
||||
CPPUNIT_ASSERT_MESSAGE("allocator value semantics 2 after fragmentation", aPool.get(nIdx2) == 1 );
|
||||
|
||||
nIdx3 = aPool.store(2);
|
||||
CPPUNIT_ASSERT_MESSAGE("allocator value semantics 3 after fragmentation", aPool.get(nIdx3) == 2 );
|
||||
}
|
||||
|
||||
// Change the following lines only, if you add, remove or rename
|
||||
// member functions of the current class,
|
||||
// because these macros are need by auto register mechanism.
|
||||
|
||||
CPPUNIT_TEST_SUITE(vector_pool_test);
|
||||
CPPUNIT_TEST(testPoolBasics);
|
||||
CPPUNIT_TEST(testPoolValueSemantics);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(vector_pool_test, "vector pool test");
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// NOADDITIONAL;
|
||||
|
Reference in New Issue
Block a user