SourceXtractorPlusPlus 0.21
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
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
25
26namespace SourceXtractor {
27
30
31bool 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
37 str << m_source.get() << "[" << m_source->getRepr() << "] " << m_tile_x << "," << m_tile_y;
38 return str.str();
39}
40
41
42TileManager::TileManager() : m_tile_width(256), m_tile_height(256),
43 m_max_memory(100 * 1024L * 1024L), m_total_memory_used(0) {
44}
45
47 try {
49 } catch (const std::exception& e) {
50 s_tile_logger.error() << "Error while saving tiles at destruction: " << e.what();
51 }
52}
53
55 flush();
56
57 boost::lock_guard<boost::shared_mutex> wr_lock(m_mutex);
60 m_max_memory = max_memory * 1024L * 1024L;
61}
62
64 // empty anything still stored in cache
66
67 boost::lock_guard<boost::shared_mutex> wr_lock(m_mutex);
68 m_tile_list.clear();
69 m_tile_map.clear();
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 */
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
87 }
88 return nullptr;
89}
90
91/*
92 * If the mutex does not exist, we need an upgradable lock
93 */
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);
100 }
101 return mit->second;
102}
103
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.
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
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);
137 return tile;
138}
139
146
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
156 return m_tile_width;
157}
158
160 return m_tile_height;
161}
162
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
178 assert(m_tile_list.size() > 0);
179 auto tile_to_remove = m_tile_list.back();
181 m_tile_list.pop_back();
182 }
183}
184
186#ifndef NDEBUG
187 s_tile_logger.debug() << "Cache miss " << key;
188#endif
189
191 m_tile_list.push_front(key);
192 m_total_memory_used += tile->getTileMemorySize();
193}
194
195}
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
static Logging getLogger(const std::string &name="")
std::unordered_map< const ImageSource *, std::shared_ptr< boost::mutex > > m_mutex_map
std::shared_ptr< ImageTile > getTileForPixel(int x, int y, std::shared_ptr< const ImageSource > source)
boost::shared_mutex m_mutex
std::list< TileKey > m_tile_list
std::shared_ptr< ImageTile > tryTileFromCache(const TileKey &key)
void removeTile(TileKey tile_key)
void addTile(TileKey key, std::shared_ptr< ImageTile > tile)
void setOptions(int tile_width, int tile_height, int max_memory)
static std::shared_ptr< TileManager > getInstance()
std::unordered_map< TileKey, std::shared_ptr< ImageTile > > m_tile_map
std::shared_ptr< boost::mutex > & getMutexForImageSource(const ImageSource *)
T min(T... args)
static Elements::Logging s_tile_logger
static std::shared_ptr< TileManager > s_instance
T str(T... args)
bool operator==(const TileKey &other) const
std::shared_ptr< const ImageSource > m_source
Definition TileManager.h:43
std::string getRepr() const