SourceXtractorPlusPlus  0.19
SourceXtractor++, the next generation SExtractor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
26 namespace SourceXtractor {
27 
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 
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 
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 
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();
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
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  */
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 
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));
137  return tile;
138 }
139 
141  if (s_instance == nullptr) {
142  s_instance = std::make_shared<TileManager>();
143  }
144  return s_instance;
145 }
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();
180  removeTile(tile_to_remove);
181  m_tile_list.pop_back();
182  }
183 }
184 
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 }
std::list< TileKey > m_tile_list
Definition: TileManager.h:116
std::string getRepr() const
Definition: TileManager.cpp:35
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
std::shared_ptr< boost::mutex > & getMutexForImageSource(const ImageSource *)
Definition: TileManager.cpp:94
std::shared_ptr< ImageTile > getTileForPixel(int x, int y, std::shared_ptr< const ImageSource > source)
void debug(const std::string &logMessage)
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
void removeTile(TileKey tile_key)
STL class.
T min(T...args)
constexpr double e
T what(T...args)
static Elements::Logging s_tile_logger
Definition: TileManager.cpp:29
std::shared_ptr< ImageTile > tryTileFromCache(const TileKey &key)
Definition: TileManager.cpp:78
T dynamic_pointer_cast(T...args)
STL class.
std::unordered_map< const ImageSource *, std::shared_ptr< boost::mutex > > m_mutex_map
Definition: TileManager.h:115
T get(T...args)
std::unordered_map< TileKey, std::shared_ptr< ImageTile > > m_tile_map
Definition: TileManager.h:114
void error(const std::string &logMessage)
boost::shared_mutex m_mutex
Definition: TileManager.h:118
void addTile(TileKey key, std::shared_ptr< ImageTile > tile)
static std::shared_ptr< TileManager > s_instance
Definition: TileManager.cpp:28
static std::shared_ptr< TileManager > getInstance()
static Logging getLogger(const std::string &name="")
std::shared_ptr< const ImageSource > m_source
Definition: TileManager.h:43
bool operator==(const TileKey &other) const
Definition: TileManager.cpp:31
void setOptions(int tile_width, int tile_height, int max_memory)
Definition: TileManager.cpp:54