iipsrv 1.1
iipsrv is an advanced high-performance feature-rich image server for web-based streamed viewing and zooming of ultra high-resolution images
Cache.h
1// Tile Cache Class
2
3/* IIP Image Server
4
5 Copyright (C) 2005-2019 Ruven Pillay.
6 Based on an LRU cache by Patrick Audley <http://blackcat.ca/lifeline/query.php/tag=LRU_CACHE>
7 Copyright (C) 2004 by Patrick Audley
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
22*/
23
24
25
26#ifndef _CACHE_H
27#define _CACHE_H
28
29
30// Fix missing snprintf in Windows
31#if defined _MSC_VER && _MSC_VER<1900
32#define snprintf _snprintf
33#endif
34
35
36
37// Test for available map types. Try to use an efficient hashed map type if possible
38// and define this as HASHMAP, which we can then use elsewhere.
39#if defined(HAVE_UNORDERED_MAP)
40#include <unordered_map>
41#define HASHMAP std::unordered_map
42
43#elif defined(HAVE_TR1_UNORDERED_MAP)
44#include <tr1/unordered_map>
45#define HASHMAP std::tr1::unordered_map
46
47// Use the gcc hash_map extension if we have it
48#elif defined(HAVE_EXT_HASH_MAP)
49#include <ext/hash_map>
50#define HASHMAP __gnu_cxx::hash_map
51
52/* Explicit template specialization of hash of a string class,
53 which just uses the internal char* representation as a wrapper.
54 Required for older versions of gcc as hashing on a string is
55 not supported.
56 */
57namespace __gnu_cxx {
58 template <>
59 struct hash<std::string> {
60 size_t operator() (const std::string& x) const {
61 return hash<const char*>()(x.c_str());
62 }
63 };
64}
65
66// If no hash type available, just use map
67#else
68#include <map>
69#define HASHMAP std::map
70
71#endif // End of #if defined
72
73
74
75// Try to use the gcc high performance memory pool allocator (available in gcc >= 3.4)
76#ifdef HAVE_EXT_POOL_ALLOCATOR
77#include <ext/pool_allocator.h>
78#endif
79
80
81
82#include <iostream>
83#include <list>
84#include <string>
85#include "RawTile.h"
86
87
88
90
91class Cache {
92
93
94 private:
95
97 int tileSize;
98
100 unsigned long maxSize;
101
103 unsigned long currentSize;
104
106#ifdef HAVE_EXT_POOL_ALLOCATOR
107 typedef std::list < std::pair<const std::string,RawTile>,
108 __gnu_cxx::__pool_alloc< std::pair<const std::string,RawTile> > > TileList;
109#else
110 typedef std::list < std::pair<const std::string,RawTile> > TileList;
111#endif
112
114 typedef std::list < std::pair<const std::string,RawTile> >::iterator List_Iter;
115
117#ifdef HAVE_EXT_POOL_ALLOCATOR
118 typedef HASHMAP < std::string, List_Iter,
119 __gnu_cxx::hash< const std::string >,
120 std::equal_to< const std::string >,
121 __gnu_cxx::__pool_alloc< std::pair<const std::string, List_Iter> >
122 > TileMap;
123#else
124 typedef HASHMAP < std::string,List_Iter > TileMap;
125#endif
126
127
129 TileList tileList;
130
132 TileMap tileMap;
133
134
136
140 TileMap::iterator _touch( const std::string &key ) {
141 TileMap::iterator miter = tileMap.find( key );
142 if( miter == tileMap.end() ) return miter;
143 // Move the found node to the head of the list.
144 tileList.splice( tileList.begin(), tileList, miter->second );
145 return miter;
146 }
147
148
150
154 void _remove( const TileMap::iterator &miter ) {
155 // Reduce our current size counter
156 currentSize -= ( (miter->second->second).dataLength +
157 ( (miter->second->second).filename.capacity() + (miter->second->first).capacity() )*sizeof(char) +
158 tileSize );
159 tileList.erase( miter->second );
160 tileMap.erase( miter );
161 }
162
163
165
166 void _remove( const std::string &key ) {
167 TileMap::iterator miter = tileMap.find( key );
168 this->_remove( miter );
169 }
170
171
172
173 public:
174
176
177 Cache( float max ) {
178 maxSize = (unsigned long)(max*1024000) ; currentSize = 0;
179 // 64 chars added at the end represents an average string length
180 tileSize = sizeof( RawTile ) + sizeof( std::pair<const std::string,RawTile> ) +
181 sizeof( std::pair<const std::string, List_Iter> ) + sizeof(char)*64 + sizeof(List_Iter);
182 };
183
184
187 clear();
188 }
189
190
192 void clear() {
193 tileList.clear();
194 tileMap.clear();
195 currentSize = 0;
196 }
197
198
200
201 void insert( const RawTile& r ) {
202
203 if( maxSize == 0 ) return;
204
205 std::string key = this->getIndex( r.filename, r.resolution, r.tileNum,
207
208 // Touch the key, if it exists
209 TileMap::iterator miter = this->_touch( key );
210
211 // Check whether this tile exists in our cache
212 if( miter != tileMap.end() ){
213 // Check the timestamp and delete if necessary
214 if( miter->second->second.timestamp < r.timestamp ){
215 this->_remove( miter );
216 }
217 // If this index already exists and it is up to date, do nothing
218 else return;
219 }
220
221 // Store the key if it doesn't already exist in our cache
222 // Ok, do the actual insert at the head of the list
223 tileList.push_front( std::make_pair(key,r) );
224
225 // And store this in our map
226 List_Iter liter = tileList.begin();
227 tileMap[ key ] = liter;
228
229 // Update our total current size variable. Use the string::capacity function
230 // rather than length() as std::string can allocate slightly more than necessary
231 // The +1 is for the terminating null byte
232 currentSize += (r.dataLength + (r.filename.capacity()+key.capacity())*sizeof(char) + tileSize);
233
234 // Check to see if we need to remove an element due to exceeding max_size
235 while( currentSize > maxSize ) {
236 // Remove the last element
237 liter = tileList.end();
238 --liter;
239 this->_remove( liter->first );
240 }
241
242 }
243
244
246 unsigned int getNumElements() { return tileList.size(); }
247
248
250 float getMemorySize() { return (float) ( currentSize / 1024000.0 ); }
251
252
254
264 RawTile* getTile( std::string f, int r, int t, int h, int v, CompressionType c, int q ) {
265
266 if( maxSize == 0 ) return NULL;
267
268 std::string key = this->getIndex( f, r, t, h, v, c, q );
269
270 TileMap::iterator miter = tileMap.find( key );
271 if( miter == tileMap.end() ) return NULL;
272 this->_touch( key );
273
274 return &(miter->second->second);
275 }
276
277
279
289 std::string getIndex( std::string f, int r, int t, int h, int v, CompressionType c, int q ) {
290 char tmp[1024];
291 snprintf( tmp, 1024, "%s:%d:%d:%d:%d:%d:%d", f.c_str(), r, t, h, v, c, q );
292 return std::string( tmp );
293 }
294
295
296
297};
298
299
300
301#endif
Cache to store raw tile data.
Definition Cache.h:91
Cache(float max)
Constructor.
Definition Cache.h:177
float getMemorySize()
Return the number of MB stored.
Definition Cache.h:250
unsigned int getNumElements()
Return the number of tiles in the cache.
Definition Cache.h:246
RawTile * getTile(std::string f, int r, int t, int h, int v, CompressionType c, int q)
Get a tile from the cache.
Definition Cache.h:264
void insert(const RawTile &r)
Insert a tile.
Definition Cache.h:201
void clear()
Empty the cache.
Definition Cache.h:192
std::string getIndex(std::string f, int r, int t, int h, int v, CompressionType c, int q)
Create a hash index.
Definition Cache.h:289
~Cache()
Destructor.
Definition Cache.h:186
Class to represent a single image tile.
Definition RawTile.h:45
std::string filename
Name of the file from which this tile comes.
Definition RawTile.h:68
time_t timestamp
Tile timestamp.
Definition RawTile.h:71
int vSequence
The vertical angle to which this tile belongs.
Definition RawTile.h:59
int tileNum
The tile number for this tile.
Definition RawTile.h:50
int resolution
The resolution to which this tile belongs.
Definition RawTile.h:53
unsigned int dataLength
The size of the data pointed to by data.
Definition RawTile.h:82
CompressionType compressionType
Compression type.
Definition RawTile.h:62
int quality
Compression rate or quality.
Definition RawTile.h:65
int hSequence
The horizontal angle to which this tile belongs.
Definition RawTile.h:56