SourceXtractorPlusPlus
0.21
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
}
x
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
Definition
MoffatModelFittingTask.cpp:94
y
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
Definition
MoffatModelFittingTask.cpp:94
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::function
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::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.10.0