From 53541b81347ef65263083a92497da966cbfe0d6b Mon Sep 17 00:00:00 2001 From: Martin Nolte <mnolte@dune-project.org> Date: Tue, 7 Aug 2012 14:20:10 +0000 Subject: [PATCH] add capacity manager for adaptive simulations (will also shrink the array) [[Imported from SVN: r6889]] --- dune/common/container/dynamicarray.hh | 75 +++++++++++++++++++ .../common/container/test/dynamicarraytest.cc | 7 ++ 2 files changed, 82 insertions(+) diff --git a/dune/common/container/dynamicarray.hh b/dune/common/container/dynamicarray.hh index 8dce874e9..d59f3db8d 100644 --- a/dune/common/container/dynamicarray.hh +++ b/dune/common/container/dynamicarray.hh @@ -4,6 +4,7 @@ #define DUNE_DYNAMICARRAY_HH #include <cassert> +#include <cmath> #include <memory> #include <dune/common/exceptions.hh> @@ -105,6 +106,80 @@ namespace Dune + // AdaptiveCapacityManager + // ----------------------- + + template< class sz_t = std::size_t > + class AdaptiveCapacityManager + { + typedef AdaptiveCapacityManager< sz_t > This; + + public: + typedef sz_t size_type; + + template< class _sz_t > + struct rebind { typedef AdaptiveCapacityManager< _sz_t > other; }; + + AdaptiveCapacityManager ( const double factor = 1.125 ) + : capacity_( 0 ), factor_( factor ) + { + assert( factor_ >= 1.0 ); + } + + template< class _sz_t > + AdaptiveCapacityManager ( const AdaptiveCapacityManager< _sz_t > &other ) + : capacity_( 0 ), factor_( other.factor_ ) + {} + + AdaptiveCapacityManager ( const This &other ) + : capacity_( 0 ), factor_( other.factor_ ) + {} + + template< class _sz_t > + const This &operator= ( const AdaptiveCapacityManager< _sz_t > &other ) + { + capacity_ = 0; + factor_ = other.factor_; + return *this; + } + + const This &operator= ( const This &other ) + { + capacity_ = 0; + factor_ = other.factor_; + return *this; + } + + size_type capacity ( size_type current_size ) const { return capacity_; } + + std::pair< size_type, size_type > + reserve ( size_type current_size, size_type desired_capacity ) + { + const size_type current_capacity = capacity_; + if( capacity_ < desired_capacity ) + capacity_ = (size_type) std::ceil( factor_ * desired_capacity ); + return std::make_pair( current_capacity, capacity_ ); + } + + std::pair< size_type, size_type > + resize ( size_type current_size, size_type desired_size ) + { + const size_type overEstimate = (size_type) std::ceil( factor_ * desired_size ); + if( (desired_size <= capacity_) && (overEstimate >= capacity_) ) + return std::make_pair( capacity_, capacity_ ); + + const size_type current_capacity = capacity_; + capacity_ = overEstimate; + return std::make_pair( current_capacity, capacity_ ); + } + + private: + size_type capacity_; + double factor_; + }; + + + // DynamicArray // ------------ diff --git a/dune/common/container/test/dynamicarraytest.cc b/dune/common/container/test/dynamicarraytest.cc index d1ff86fcf..ffd1229fd 100644 --- a/dune/common/container/test/dynamicarraytest.cc +++ b/dune/common/container/test/dynamicarraytest.cc @@ -15,6 +15,9 @@ int main ( int argc, char **argv ) std::cout << "sizeof( Dune::DynamicArray< int, Dune::StaticCapacityManager<> > ) = " << sizeof( Dune::DynamicArray< int, Dune::StaticCapacityManager<> > ) << std::endl; + std::cout << "sizeof( Dune::DynamicArray< int, Dune::AdaptiveCapacityManager<> > ) = " + << sizeof( Dune::DynamicArray< int, Dune::AdaptiveCapacityManager<> > ) << std::endl; + Dune::DynamicArray< int > a( 4 ); for( int i = 0; i < 4; ++i ) a[ i ] = i+20; @@ -23,5 +26,9 @@ int main ( int argc, char **argv ) for( int i = 0; i < 4; ++i ) b[ i ] = a[ i ] + 20; + Dune::DynamicArray< int, Dune::AdaptiveCapacityManager<> > c( 4 ); + for( int i = 0; i < 4; ++i ) + c[ i ] = b[ i ] + 20; + return 0; } -- GitLab