00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _CACHE_H
00027 #define _CACHE_H
00028
00029
00030
00031 #undef __DEPRECATED
00032
00033
00034 #ifdef __GNUC__
00035
00036 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || (__GNUC__ >= 4)
00037 #define USE_HASHMAP 1
00038 #include <ext/hash_map>
00039 namespace __gnu_cxx
00040 {
00041 template<> struct hash< const std::string > {
00042 size_t operator()( const std::string& x ) const {
00043 return hash< const char* >()( x.c_str() );
00044 }
00045 };
00046 }
00047 #endif
00048
00049
00050 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)
00051 #define POOL_ALLOCATOR 1
00052 #include <ext/pool_allocator.h>
00053 #endif
00054
00055 #endif
00056
00057
00058 #ifndef USE_HASHMAP
00059 #include <map>
00060 #endif
00061
00062 #include <iostream>
00063 #include <list>
00064 #include <string>
00065 #include "RawTile.h"
00066
00067
00068
00070
00071 class Cache {
00072
00073
00074 private:
00075
00077 unsigned long maxSize;
00078
00080 int tileSize;
00081
00083 unsigned long currentSize;
00084
00086 #ifdef POOL_ALLOCATOR
00087 typedef std::list < std::pair<const std::string,RawTile>,
00088 __gnu_cxx::__pool_alloc< std::pair<const std::string,RawTile> > > TileList;
00089 #else
00090 typedef std::list < std::pair<const std::string,RawTile> > TileList;
00091 #endif
00092
00094 typedef std::list < std::pair<const std::string,RawTile> >::iterator List_Iter;
00095
00097 #ifdef USE_HASHMAP
00098 #ifdef POOL_ALLOCATOR
00099 typedef __gnu_cxx::hash_map < const std::string, List_Iter,
00100 __gnu_cxx::hash< const std::string >,
00101 std::equal_to< const std::string >,
00102 __gnu_cxx::__pool_alloc< std::pair<const std::string, List_Iter> >
00103 > TileMap;
00104 #else
00105 typedef __gnu_cxx::hash_map < const std::string,List_Iter > TileMap;
00106 #endif
00107 #else
00108 typedef std::map < const std::string,List_Iter > TileMap;
00109 #endif
00110
00112 TileList tileList;
00113
00115 TileMap tileMap;
00116
00117
00119
00123 TileMap::iterator _touch( const std::string &key ) {
00124 TileMap::iterator miter = tileMap.find( key );
00125 if( miter == tileMap.end() ) return miter;
00126
00127 tileList.splice( tileList.begin(), tileList, miter->second );
00128 return miter;
00129 }
00130
00131
00133
00137 void _remove( const TileMap::iterator &miter ) {
00138
00139 currentSize -= ( (miter->second->second).dataLength +
00140 ((miter->second->second).filename.capacity()+1)*sizeof(char) +
00141 tileSize );
00142 tileList.erase( miter->second );
00143 tileMap.erase( miter );
00144 }
00145
00146
00148
00149 void _remove( const std::string &key ) {
00150 TileMap::iterator miter = tileMap.find( key );
00151 this->_remove( miter );
00152 }
00153
00154
00155
00156 public:
00157
00159
00160 Cache( float max ) {
00161 maxSize = (unsigned long)(max*1024000) ; currentSize = 0;
00162
00163 tileSize = sizeof( RawTile ) + sizeof( std::pair<const std::string,RawTile> ) +
00164 sizeof( std::pair<const std::string, List_Iter> ) + 128;
00165 };
00166
00167
00169 ~Cache() {
00170 tileList.clear();
00171 tileMap.clear();
00172 }
00173
00174
00176
00177 void insert( const RawTile& r ) {
00178
00179 if( maxSize == 0 ) return;
00180
00181 std::string key = this->getIndex( r.filename, r.resolution, r.tileNum,
00182 r.hSequence, r.vSequence, r.compressionType, r.quality );
00183
00184
00185 TileMap::iterator miter = this->_touch( key );
00186
00187
00188 if( miter != tileMap.end() ){
00189
00190 if( miter->second->second.timestamp < r.timestamp ){
00191 this->_remove( miter );
00192 }
00193
00194 else return;
00195 }
00196
00197
00198
00199 tileList.push_front( std::make_pair(key,r) );
00200
00201
00202 List_Iter liter = tileList.begin();
00203 tileMap[ key ] = liter;
00204
00205
00206
00207
00208 currentSize += (r.dataLength + (r.filename.capacity()+1)*sizeof(char) + tileSize);
00209
00210
00211 while( currentSize > maxSize ) {
00212
00213 liter = tileList.end();
00214 --liter;
00215 this->_remove( liter->first );
00216 }
00217
00218 }
00219
00220
00222 unsigned int getNumElements() { return tileList.size(); }
00223
00224
00226 float getMemorySize() { return (float) ( currentSize / 1024000.0 ); }
00227
00228
00230
00240 RawTile* getTile( std::string f, int r, int t, int h, int v, CompressionType c, int q ) {
00241
00242 if( maxSize == 0 ) return NULL;
00243
00244 std::string key = this->getIndex( f, r, t, h, v, c, q );
00245
00246 TileMap::iterator miter = tileMap.find( key );
00247 if( miter == tileMap.end() ) return NULL;
00248 this->_touch( key );
00249
00250 return &(miter->second->second);
00251 }
00252
00253
00255
00265 std::string getIndex( std::string f, int r, int t, int h, int v, CompressionType c, int q ) {
00266 char tmp[1024];
00267 snprintf( tmp, 1024, "%s:%d:%d:%d:%d:%d:%d", f.c_str(), r, t, h, v, c, q );
00268 return std::string( tmp );
00269 }
00270
00271
00272
00273 };
00274
00275
00276
00277 #endif