iipsrv 1.2
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-2022 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 <list>
83#include <string>
84#include "RawTile.h"
85
86
87
89
90class Cache {
91
92
93 private:
94
96 int tileSize;
97
99 unsigned long maxSize;
100
102 unsigned long currentSize;
103
105#ifdef HAVE_EXT_POOL_ALLOCATOR
106 typedef std::list < std::pair<const std::string,RawTile>,
107 __gnu_cxx::__pool_alloc< std::pair<const std::string,RawTile> > > TileList;
108#else
109 typedef std::list < std::pair<const std::string,RawTile> > TileList;
110#endif
111
113 typedef std::list < std::pair<const std::string,RawTile> >::iterator List_Iter;
114
116#ifdef HAVE_EXT_POOL_ALLOCATOR
117 typedef HASHMAP < std::string, List_Iter,
118 __gnu_cxx::hash< const std::string >,
119 std::equal_to< const std::string >,
120 __gnu_cxx::__pool_alloc< std::pair<const std::string, List_Iter> >
121 > TileMap;
122#else
123 typedef HASHMAP < std::string,List_Iter > TileMap;
124#endif
125
126
128 TileList tileList;
129
131 TileMap tileMap;
132
133
135
139 TileMap::iterator _touch( const std::string &key ) {
140 TileMap::iterator miter = tileMap.find( key );
141 if( miter == tileMap.end() ) return miter;
142 // Move the found node to the head of the list.
143 tileList.splice( tileList.begin(), tileList, miter->second );
144 return miter;
145 }
146
147
149
153 void _remove( const TileMap::iterator &miter ) {
154 // Reduce our current size counter
155 currentSize -= ( (miter->second->second).dataLength +
156 ( (miter->second->second).filename.capacity() + (miter->second->first).capacity() )*sizeof(char) +
157 tileSize );
158 tileList.erase( miter->second );
159 tileMap.erase( miter );
160 }
161
162
164
165 void _remove( const std::string &key ) {
166 TileMap::iterator miter = tileMap.find( key );
167 this->_remove( miter );
168 }
169
170
171
172 public:
173
175
176 Cache( const float max ) {
177 maxSize = (unsigned long)(max*1024000) ; currentSize = 0;
178 // 64 chars added at the end represents an average string length
179 tileSize = sizeof( RawTile ) + sizeof( std::pair<const std::string,RawTile> ) +
180 sizeof( std::pair<const std::string, List_Iter> ) + sizeof(char)*64 + sizeof(List_Iter);
181 };
182
183
186 clear();
187 }
188
189
191 void clear() {
192 tileList.clear();
193 tileMap.clear();
194 currentSize = 0;
195 }
196
197
199
200 void insert( const RawTile& r ) {
201
202 if( maxSize == 0 ) return;
203
204 std::string key = this->getIndex( r.filename, r.resolution, r.tileNum,
206
207 // Touch the key, if it exists
208 TileMap::iterator miter = this->_touch( key );
209
210 // Check whether this tile exists in our cache
211 if( miter != tileMap.end() ){
212 // Check the timestamp and delete if necessary
213 if( miter->second->second.timestamp < r.timestamp ){
214 this->_remove( miter );
215 }
216 // If this index already exists and it is up to date, do nothing
217 else return;
218 }
219
220 // Store the key if it doesn't already exist in our cache
221 // Ok, do the actual insert at the head of the list
222 tileList.push_front( std::make_pair(key,r) );
223
224 // And store this in our map
225 List_Iter liter = tileList.begin();
226 tileMap[ key ] = liter;
227
228 // Update our total current size variable. Use the string::capacity function
229 // rather than length() as std::string can allocate slightly more than necessary
230 // The +1 is for the terminating null byte
231 currentSize += (r.dataLength + (r.filename.capacity()+key.capacity())*sizeof(char) + tileSize);
232
233 // Check to see if we need to remove an element due to exceeding max_size
234 while( currentSize > maxSize ) {
235 // Remove the last element
236 liter = tileList.end();
237 --liter;
238 this->_remove( liter->first );
239 }
240
241 }
242
243
245 unsigned int getNumElements() const { return tileList.size(); }
246
247
249 float getMemorySize() const { return (float) ( currentSize / 1024000.0 ); }
250
251
253
263 RawTile* getTile( const std::string& f, int r, int t, int h, int v, CompressionType c, int q ) {
264
265 if( maxSize == 0 ) return NULL;
266
267 std::string key = this->getIndex( f, r, t, h, v, c, q );
268
269 TileMap::iterator miter = tileMap.find( key );
270 if( miter == tileMap.end() ) return NULL;
271 this->_touch( key );
272
273 return &(miter->second->second);
274 }
275
276
278
288 std::string getIndex( const std::string& f, int r, int t, int h, int v, CompressionType c, int q ) const {
289 char tmp[1024];
290 snprintf( tmp, 1024, "%s:%d:%d:%d:%d:%d:%d", f.c_str(), r, t, h, v, c, q );
291 return std::string( tmp );
292 }
293
294
295
296};
297
298
299
300#endif
Cache to store raw tile data.
Definition: Cache.h:90
unsigned int getNumElements() const
Return the number of tiles in the cache.
Definition: Cache.h:245
float getMemorySize() const
Return the number of MB stored.
Definition: Cache.h:249
RawTile * getTile(const std::string &f, int r, int t, int h, int v, CompressionType c, int q)
Get a tile from the cache.
Definition: Cache.h:263
void insert(const RawTile &r)
Insert a tile.
Definition: Cache.h:200
void clear()
Empty the cache.
Definition: Cache.h:191
Cache(const float max)
Constructor.
Definition: Cache.h:176
~Cache()
Destructor.
Definition: Cache.h:185
std::string getIndex(const std::string &f, int r, int t, int h, int v, CompressionType c, int q) const
Create a hash index.
Definition: Cache.h:288
Class to represent a single image tile.
Definition: RawTile.h:47
uint32_t dataLength
The size of the data pointed to by the data pointer in bytes.
Definition: RawTile.h:94
std::string filename
Name of the file from which this tile comes.
Definition: RawTile.h:52
time_t timestamp
Tile timestamp.
Definition: RawTile.h:76
int vSequence
The vertical angle to which this tile belongs.
Definition: RawTile.h:88
int tileNum
The tile number for this tile.
Definition: RawTile.h:79
int resolution
The resolution number to which this tile belongs.
Definition: RawTile.h:82
CompressionType compressionType
Compression type.
Definition: RawTile.h:70
int quality
Compression rate or quality.
Definition: RawTile.h:73
int hSequence
The horizontal angle to which this tile belongs.
Definition: RawTile.h:85