36 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || (__GNUC__ >= 4)
38 #include <ext/hash_map>
41 template<>
struct hash< const std::string > {
42 size_t operator()(
const std::string& x )
const {
43 return hash< const char* >()( x.c_str() );
50 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)
51 #define POOL_ALLOCATOR 1
52 #include <ext/pool_allocator.h>
65 #define snprintf _snprintf
87 unsigned long maxSize;
90 unsigned long currentSize;
94 typedef std::list < std::pair<const std::string,RawTile>,
95 __gnu_cxx::__pool_alloc< std::pair<const std::string,RawTile> > > TileList;
97 typedef std::list < std::pair<const std::string,RawTile> > TileList;
101 typedef std::list < std::pair<const std::string,RawTile> >::iterator List_Iter;
105 #ifdef POOL_ALLOCATOR
106 typedef __gnu_cxx::hash_map <
const std::string, List_Iter,
107 __gnu_cxx::hash< const std::string >,
108 std::equal_to< const std::string >,
109 __gnu_cxx::__pool_alloc< std::pair<const std::string, List_Iter> >
112 typedef __gnu_cxx::hash_map < const std::string,List_Iter > TileMap;
115 typedef std::map < const std::string,List_Iter > TileMap;
130 TileMap::iterator _touch(
const std::string &key ) {
131 TileMap::iterator miter = tileMap.find( key );
132 if( miter == tileMap.end() )
return miter;
134 tileList.splice( tileList.begin(), tileList, miter->second );
144 void _remove(
const TileMap::iterator &miter ) {
146 currentSize -= ( (miter->second->second).dataLength +
147 ( (miter->second->second).filename.capacity() + (miter->second->first).capacity() )*
sizeof(
char) +
149 tileList.erase( miter->second );
150 tileMap.erase( miter );
156 void _remove(
const std::string &key ) {
157 TileMap::iterator miter = tileMap.find( key );
158 this->_remove( miter );
168 maxSize = (
unsigned long)(max*1024000) ; currentSize = 0;
170 tileSize =
sizeof(
RawTile ) +
sizeof( std::pair<const std::string,RawTile> ) +
171 sizeof( std::pair<const std::string, List_Iter> ) +
sizeof(
char)*64 +
sizeof(List_Iter);
186 if( maxSize == 0 )
return;
192 TileMap::iterator miter = this->_touch( key );
195 if( miter != tileMap.end() ){
197 if( miter->second->second.timestamp < r.
timestamp ){
198 this->_remove( miter );
206 tileList.push_front( std::make_pair(key,r) );
209 List_Iter liter = tileList.begin();
210 tileMap[ key ] = liter;
215 currentSize += (r.
dataLength + (r.
filename.capacity()+key.capacity())*
sizeof(
char) + tileSize);
218 while( currentSize > maxSize ) {
220 liter = tileList.end();
222 this->_remove( liter->first );
247 RawTile*
getTile( std::string f,
int r,
int t,
int h,
int v, CompressionType c,
int q ) {
249 if( maxSize == 0 )
return NULL;
251 std::string key = this->
getIndex( f, r, t, h, v, c, q );
253 TileMap::iterator miter = tileMap.find( key );
254 if( miter == tileMap.end() )
return NULL;
257 return &(miter->second->second);
272 std::string
getIndex( std::string f,
int r,
int t,
int h,
int v, CompressionType c,
int q ) {
274 snprintf( tmp, 1024,
"%s:%d:%d:%d:%d:%d:%d", f.c_str(), r, t, h, v, c, q );
275 return std::string( tmp );