SourceXtractorPlusPlus
1.0.3
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
SEFramework
src
lib
Image
TileManager.cpp
Go to the documentation of this file.
1
17
/*
18
* TileManager.cpp
19
*
20
* Created on: Feb 23, 2018
21
* Author: mschefer
22
*/
23
24
#include "
SEFramework/Image/TileManager.h
"
25
26
namespace
SourceXtractor
{
27
28
static
std::shared_ptr<TileManager>
s_instance
;
29
static
Elements::Logging
s_tile_logger
=
Elements::Logging::getLogger
(
"TileManager"
);
30
31
bool
TileKey::operator==
(
const
TileKey
& other)
const
{
32
return
m_source
== other.
m_source
&&
m_tile_x
== other.
m_tile_x
&&
m_tile_y
== other.
m_tile_y
;
33
}
34
35
std::string
TileKey::getRepr
()
const
{
36
std::ostringstream
str;
37
str <<
m_source
.get() <<
"["
<<
m_source
->getRepr() <<
"] "
<<
m_tile_x
<<
","
<<
m_tile_y
;
38
return
str.
str
();
39
}
40
41
42
TileManager::TileManager
() :
m_tile_width
(256),
m_tile_height
(256),
43
m_max_memory
(100 * 1024L * 1024L),
m_total_memory_used
(0) {
44
}
45
46
TileManager::~TileManager
() {
47
try
{
48
saveAllTiles
();
49
}
catch
(
const
std::exception
& e) {
50
s_tile_logger
.error() <<
"Error while saving tiles at destruction: "
<< e.what();
51
}
52
}
53
54
void
TileManager::setOptions
(
int
tile_width,
int
tile_height,
int
max_memory) {
55
flush
();
56
57
boost::lock_guard<boost::shared_mutex> wr_lock(
m_mutex
);
58
m_tile_width
= tile_width;
59
m_tile_height
= tile_height;
60
m_max_memory
= max_memory * 1024L * 1024L;
61
}
62
63
void
TileManager::flush
() {
64
// empty anything still stored in cache
65
saveAllTiles
();
66
67
boost::lock_guard<boost::shared_mutex> wr_lock(
m_mutex
);
68
m_tile_list
.clear();
69
m_tile_map
.clear();
70
m_total_memory_used
= 0;
71
}
72
73
/*
74
* boost::upgrade_lock can only be acquired by a single thread, even if none of them
75
* ends needing an exclusive lock. Cache lookup must be done with a shared_lock instead
76
* so multiples can retrieve from the cache at the same time.
77
*/
78
std::shared_ptr<ImageTile>
TileManager::tryTileFromCache
(
const
TileKey
& key) {
79
boost::shared_lock<boost::shared_mutex> shared_rd_lock(
m_mutex
);
80
81
auto
it =
m_tile_map
.find(key);
82
if
(it !=
m_tile_map
.end()) {
83
#ifndef NDEBUG
84
s_tile_logger
.debug() <<
"Cache hit "
<< key;
85
#endif
86
return
std::dynamic_pointer_cast<ImageTile>
(it->second);
87
}
88
return
nullptr
;
89
}
90
91
/*
92
* If the mutex does not exist, we need an upgradable lock
93
*/
94
std::shared_ptr<boost::mutex>
&
TileManager::getMutexForImageSource
(
const
ImageSource
*src_ptr) {
95
boost::upgrade_lock<boost::shared_mutex> upgrade_lock(
m_mutex
);
96
auto
mit =
m_mutex_map
.find(src_ptr);
97
if
(mit ==
m_mutex_map
.end()) {
98
boost::upgrade_to_unique_lock<boost::shared_mutex>
unique_lock
(upgrade_lock);
99
mit =
m_mutex_map
.emplace(src_ptr,
std::make_shared<boost::mutex>
()).first;
100
}
101
return
mit->second;
102
}
103
104
std::shared_ptr<ImageTile>
TileManager::getTileForPixel
(
int
x,
int
y,
105
std::shared_ptr<const ImageSource>
source) {
106
x = x /
m_tile_width
*
m_tile_width
;
107
y = y /
m_tile_height
*
m_tile_height
;
108
TileKey
key{
std::static_pointer_cast<const ImageSource>
(source), x, y};
109
110
// Try from the cache, this can be done by multiple threads in parallel
111
auto
tile =
tryTileFromCache
(key);
112
if
(tile) {
113
return
tile;
114
}
115
116
// Cache miss, we need to ask the underlying source.
117
// First, we need a mutex only for that source, and that needs writing to the tile manager.
118
auto
img_mutex =
getMutexForImageSource
(source.
get
());
119
120
// Here we block access only to this specific image source
121
boost::lock_guard<boost::mutex> img_lock(*img_mutex);
122
123
// Try again from the cache, maybe someone put it there while we waited for the image lock
124
tile =
tryTileFromCache
(key);
125
if
(tile) {
126
return
tile;
127
}
128
129
tile = source->getImageTile(x, y,
130
std::min
(
m_tile_width
, source->getWidth() - x),
131
std::min
(
m_tile_height
, source->getHeight() - y));
132
133
// Here we need to acquire the mutex in write mode!
134
boost::lock_guard<boost::shared_mutex> wr_lock(
m_mutex
);
135
addTile
(key,
std::static_pointer_cast<ImageTile>
(tile));
136
removeExtraTiles
();
137
return
tile;
138
}
139
140
std::shared_ptr<TileManager>
TileManager::getInstance
() {
141
if
(
s_instance
==
nullptr
) {
142
s_instance
=
std::make_shared<TileManager>
();
143
}
144
return
s_instance
;
145
}
146
147
void
TileManager::saveAllTiles
() {
148
boost::lock_guard<boost::shared_mutex> wr_lock(
m_mutex
);
149
150
for
(
auto
tile_key :
m_tile_list
) {
151
m_tile_map
.at(tile_key)->saveIfModified();
152
}
153
}
154
155
int
TileManager::getTileWidth
()
const
{
156
return
m_tile_width
;
157
}
158
159
int
TileManager::getTileHeight
()
const
{
160
return
m_tile_height
;
161
}
162
163
void
TileManager::removeTile
(
TileKey
tile_key) {
164
#ifndef NDEBUG
165
s_tile_logger
.debug() <<
"Cache eviction "
<< tile_key;
166
#endif
167
168
auto
& tile =
m_tile_map
.at(tile_key);
169
170
tile->saveIfModified();
171
m_total_memory_used
-= tile->getTileMemorySize();
172
173
m_tile_map
.erase(tile_key);
174
}
175
176
void
TileManager::removeExtraTiles
() {
177
while
(
m_total_memory_used
>
m_max_memory
) {
178
assert(
m_tile_list
.size() > 0);
179
auto
tile_to_remove =
m_tile_list
.back();
180
removeTile
(tile_to_remove);
181
m_tile_list
.pop_back();
182
}
183
}
184
185
void
TileManager::addTile
(
TileKey
key,
std::shared_ptr<ImageTile>
tile) {
186
#ifndef NDEBUG
187
s_tile_logger
.debug() <<
"Cache miss "
<< key;
188
#endif
189
190
m_tile_map
[key] = tile;
191
m_tile_list
.push_front(key);
192
m_total_memory_used
+= tile->getTileMemorySize();
193
}
194
195
}
TileManager.h
std::ostringstream
std::string
Elements::Logging
Elements::Logging::getLogger
static Logging getLogger(const std::string &name="")
SourceXtractor::ImageSource
Definition
ImageSource.h:55
SourceXtractor::TileManager::m_mutex_map
std::unordered_map< const ImageSource *, std::shared_ptr< boost::mutex > > m_mutex_map
Definition
TileManager.h:115
SourceXtractor::TileManager::saveAllTiles
void saveAllTiles()
Definition
TileManager.cpp:147
SourceXtractor::TileManager::removeExtraTiles
void removeExtraTiles()
Definition
TileManager.cpp:176
SourceXtractor::TileManager::m_max_memory
long m_max_memory
Definition
TileManager.h:111
SourceXtractor::TileManager::~TileManager
virtual ~TileManager()
Definition
TileManager.cpp:46
SourceXtractor::TileManager::getTileWidth
int getTileWidth() const
Definition
TileManager.cpp:155
SourceXtractor::TileManager::getTileForPixel
std::shared_ptr< ImageTile > getTileForPixel(int x, int y, std::shared_ptr< const ImageSource > source)
Definition
TileManager.cpp:104
SourceXtractor::TileManager::flush
void flush()
Definition
TileManager.cpp:63
SourceXtractor::TileManager::m_total_memory_used
long m_total_memory_used
Definition
TileManager.h:112
SourceXtractor::TileManager::m_mutex
boost::shared_mutex m_mutex
Definition
TileManager.h:118
SourceXtractor::TileManager::m_tile_list
std::list< TileKey > m_tile_list
Definition
TileManager.h:116
SourceXtractor::TileManager::tryTileFromCache
std::shared_ptr< ImageTile > tryTileFromCache(const TileKey &key)
Definition
TileManager.cpp:78
SourceXtractor::TileManager::removeTile
void removeTile(TileKey tile_key)
Definition
TileManager.cpp:163
SourceXtractor::TileManager::getTileHeight
int getTileHeight() const
Definition
TileManager.cpp:159
SourceXtractor::TileManager::m_tile_width
int m_tile_width
Definition
TileManager.h:110
SourceXtractor::TileManager::addTile
void addTile(TileKey key, std::shared_ptr< ImageTile > tile)
Definition
TileManager.cpp:185
SourceXtractor::TileManager::m_tile_height
int m_tile_height
Definition
TileManager.h:110
SourceXtractor::TileManager::TileManager
TileManager()
Definition
TileManager.cpp:42
SourceXtractor::TileManager::setOptions
void setOptions(int tile_width, int tile_height, int max_memory)
Definition
TileManager.cpp:54
SourceXtractor::TileManager::getInstance
static std::shared_ptr< TileManager > getInstance()
Definition
TileManager.cpp:140
SourceXtractor::TileManager::m_tile_map
std::unordered_map< TileKey, std::shared_ptr< ImageTile > > m_tile_map
Definition
TileManager.h:114
SourceXtractor::TileManager::getMutexForImageSource
std::shared_ptr< boost::mutex > & getMutexForImageSource(const ImageSource *)
Definition
TileManager.cpp:94
std::exception
std::shared_ptr::get
T get(T... args)
std::make_shared
T make_shared(T... args)
std::min
T min(T... args)
SourceXtractor
Definition
Aperture.h:30
SourceXtractor::s_tile_logger
static Elements::Logging s_tile_logger
Definition
TileManager.cpp:29
SourceXtractor::s_instance
static std::shared_ptr< TileManager > s_instance
Definition
TileManager.cpp:28
std::dynamic_pointer_cast
T dynamic_pointer_cast(T... args)
std::shared_ptr
std::ostringstream::str
T str(T... args)
SourceXtractor::TileKey
Definition
TileManager.h:42
SourceXtractor::TileKey::m_tile_x
int m_tile_x
Definition
TileManager.h:44
SourceXtractor::TileKey::operator==
bool operator==(const TileKey &other) const
Definition
TileManager.cpp:31
SourceXtractor::TileKey::m_tile_y
int m_tile_y
Definition
TileManager.h:44
SourceXtractor::TileKey::m_source
std::shared_ptr< const ImageSource > m_source
Definition
TileManager.h:43
SourceXtractor::TileKey::getRepr
std::string getRepr() const
Definition
TileManager.cpp:35
std::unique_lock
Generated by
1.14.0