From 2bff302c8a8eb6768313df248b06e7f725a4ae87 Mon Sep 17 00:00:00 2001 From: Sascha Volkenandt Date: Wed, 30 May 2007 20:26:14 +0000 Subject: - new files --- cache.h | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100755 cache.h (limited to 'cache.h') diff --git a/cache.h b/cache.h new file mode 100755 index 0000000..b34c1c2 --- /dev/null +++ b/cache.h @@ -0,0 +1,89 @@ +#ifndef VGSTOOLS_CACHE_H +#define VGSTOOLS_CACHE_H + +#include +#include +#include +#include +#include +#include "stdext.h" + +/* Interface for TValue: + * size_t weight() + * bool is_newer( time_t ) + * bool load() + * + */ + +namespace vgstools { + +template< typename TKey, typename TValue > +class cache +{ +public: + typedef TKey key_type; + typedef TValue value_type; + typedef std::tr1::shared_ptr< value_type > ptr_type; + +private: + struct Value + { + ptr_type value; + std::time_t creation; + + Value( key_type const& key ) + : value( new value_type( key ) ) + , creation( 0 ) {} + }; + + typedef std::list< Value > ValueList; + typedef std::map< TKey, typename ValueList::iterator > KeyMap; + +public: + cache( size_t maxWeight ) + : m_maxWeight( maxWeight ) + , m_currentWeight( 0 ) {} + + size_t weight() const { return m_currentWeight; } + size_t count() const { return m_values.size(); } + + ptr_type get( key_type const& key ) + { + typename KeyMap::iterator it = m_lookup.find( key ); + if ( it == m_lookup.end() ) { + typename ValueList::iterator element = m_values.insert( m_values.begin(), Value( key ) ); + std::pair< typename KeyMap::iterator, bool > result = m_lookup.insert( std::make_pair( key, element ) ); + it = result.first; + } + + Value* value = &*it->second; + std::time_t now = std::time( 0 ); + if ( value->creation == 0 || !value->value->is_current() ) { + m_currentWeight -= value->value->weight(); + if ( !value->value->load() ) { + m_values.erase( it->second ); + m_lookup.erase( it ); + return ptr_type(); + } + m_currentWeight += value->value->weight(); + value->creation = now; + } + if ( it->second != m_values.begin() ) { + typename ValueList::iterator element = m_values.insert( m_values.begin(), *it->second ); + m_values.erase( it->second ); + it->second = element; + value = &*element; + } + return value->value; + } + +private: + std::size_t m_maxWeight; + std::size_t m_currentWeight; + ValueList m_values; + KeyMap m_lookup; +}; + +} // namespace vgstools + +#endif // VGSTOOLS_CACHE_H -- cgit v1.2.3