TuttleOFX
1
|
00001 #include "MemoryCache.hpp" 00002 #include <tuttle/host/attribute/Image.hpp> // to know the function getReference() 00003 #include <tuttle/common/utils/global.hpp> 00004 #include <boost/foreach.hpp> 00005 00006 #include <functional> 00007 00008 namespace tuttle { 00009 namespace host { 00010 namespace memory { 00011 00012 MemoryCache& MemoryCache::operator=( const MemoryCache& cache ) 00013 { 00014 if( &cache == this ) 00015 return *this; 00016 boost::mutex::scoped_lock lockerMap1( cache._mutexMap ); 00017 boost::mutex::scoped_lock lockerMap2( _mutexMap ); 00018 _map = cache._map; 00019 return *this; 00020 } 00021 00022 void MemoryCache::put( const std::string& identifier, const double time, CACHE_ELEMENT pData ) 00023 { 00024 boost::mutex::scoped_lock lockerMap( _mutexMap ); 00025 _map[Key( identifier, time )] = pData; 00026 } 00027 00028 CACHE_ELEMENT MemoryCache::get( const std::string& identifier, const double time ) const 00029 { 00030 boost::mutex::scoped_lock lockerMap( _mutexMap ); 00031 MAP::const_iterator itr = _map.find( Key( identifier, time ) ); 00032 00033 if( itr == _map.end() ) 00034 return CACHE_ELEMENT(); 00035 return itr->second; 00036 } 00037 00038 CACHE_ELEMENT MemoryCache::get( const std::size_t& i ) const 00039 { 00040 boost::mutex::scoped_lock lockerMap( _mutexMap ); 00041 MAP::const_iterator itr = _map.begin(); 00042 for( unsigned int j = 0; j < i && itr != _map.end(); ++j ) 00043 ++itr; 00044 00045 if( itr == _map.end() ) 00046 return CACHE_ELEMENT(); 00047 return itr->second; 00048 } 00049 00050 std::size_t MemoryCache::size() const 00051 { 00052 boost::mutex::scoped_lock lockerMap( _mutexMap ); 00053 return _map.size(); 00054 } 00055 00056 bool MemoryCache::empty() const 00057 { 00058 boost::mutex::scoped_lock lockerMap( _mutexMap ); 00059 return _map.empty(); 00060 } 00061 00062 bool MemoryCache::inCache( const CACHE_ELEMENT& pData ) const 00063 { 00064 boost::mutex::scoped_lock lockerMap( _mutexMap ); 00065 return getIteratorForValue( pData ) != _map.end(); 00066 } 00067 00068 namespace { 00069 00070 const std::string EMPTY_STRING = ""; 00071 00072 template<typename T> 00073 struct FindValuePredicate : public std::unary_function<typename T::value_type, bool> 00074 { 00075 const typename T::mapped_type & _value; 00076 FindValuePredicate( const typename T::mapped_type& value ) : _value( value ) {} 00077 00078 bool operator()( const typename T::value_type& pair ) 00079 { 00080 return pair.second == _value; 00081 } 00082 00083 }; 00084 00085 } 00086 00087 MemoryCache::MAP::const_iterator MemoryCache::getIteratorForValue( const CACHE_ELEMENT& pData ) const 00088 { 00089 return std::find_if( _map.begin(), _map.end(), FindValuePredicate<MAP>( pData ) ); 00090 } 00091 00092 MemoryCache::MAP::iterator MemoryCache::getIteratorForValue( const CACHE_ELEMENT& pData ) 00093 { 00094 return std::find_if( _map.begin(), _map.end(), FindValuePredicate<MAP>( pData ) ); 00095 } 00096 00097 double MemoryCache::getTime( const CACHE_ELEMENT& pData ) const 00098 { 00099 boost::mutex::scoped_lock lockerMap( _mutexMap ); 00100 MAP::const_iterator itr = getIteratorForValue( pData ); 00101 00102 if( itr == _map.end() ) 00103 return 0; 00104 return itr->first._time; 00105 } 00106 00107 const std::string& MemoryCache::getPluginName( const CACHE_ELEMENT& pData ) const 00108 { 00109 boost::mutex::scoped_lock lockerMap( _mutexMap ); 00110 MAP::const_iterator itr = getIteratorForValue( pData ); 00111 00112 if( itr == _map.end() ) 00113 return EMPTY_STRING; 00114 return itr->first._identifier; 00115 } 00116 00117 bool MemoryCache::remove( const CACHE_ELEMENT& pData ) 00118 { 00119 boost::mutex::scoped_lock lockerMap( _mutexMap ); 00120 const MAP::iterator itr = getIteratorForValue( pData ); 00121 00122 if( itr == _map.end() ) 00123 return false; 00124 _map.erase( itr ); 00125 return true; 00126 } 00127 00128 void MemoryCache::clearUnused() 00129 { 00130 boost::mutex::scoped_lock lockerMap( _mutexMap ); 00131 for( MAP::iterator it = _map.begin(); it != _map.end(); ) 00132 { 00133 if( it->second->getReferenceCount( ofx::imageEffect::OfxhImage::eReferenceOwnerHost ) <= 1 ) 00134 { 00135 _map.erase( it++ ); // post-increment here, increments 'it' and returns a copy of the original 'it' to be used by erase() 00136 } 00137 else 00138 { 00139 ++it; 00140 } 00141 } 00142 } 00143 00144 void MemoryCache::clearAll() 00145 { 00146 TUTTLE_LOG_DEBUG( TUTTLE_TRACE, " - MEMORYCACHE::CLEARALL - " ); 00147 boost::mutex::scoped_lock lockerMap( _mutexMap ); 00148 _map.clear(); 00149 } 00150 00151 std::ostream& operator<<( std::ostream& os, const MemoryCache& v ) 00152 { 00153 os << "size:" << v.size() << std::endl; 00154 BOOST_FOREACH( const MemoryCache::MAP::value_type& i, v._map ) 00155 { 00156 os << i.first 00157 << " id:" << i.second->getId() 00158 << " ref host:" << i.second->getReferenceCount( ofx::imageEffect::OfxhImage::eReferenceOwnerHost ) 00159 << " ref plugins:" << i.second->getReferenceCount( ofx::imageEffect::OfxhImage::eReferenceOwnerPlugin ) << std::endl; 00160 } 00161 return os; 00162 } 00163 00164 } 00165 } 00166 }