AliceVision
Photogrammetric Computer Vision Framework
cache.hpp
1 // This file is part of the AliceVision project.
2 // Copyright (c) 2016 AliceVision contributors.
3 // Copyright (c) 2012 openMVG contributors.
4 // This Source Code Form is subject to the terms of the Mozilla Public License,
5 // v. 2.0. If a copy of the MPL was not distributed with this file,
6 // You can obtain one at https://mozilla.org/MPL/2.0/.
7 
8 #pragma once
9 
10 #include "aliceVision/numeric/numeric.hpp"
11 #include <memory>
12 
13 #include <unordered_map>
14 #include <boost/multi_index_container.hpp>
15 #include <boost/multi_index/hashed_index.hpp>
16 #include <boost/multi_index/identity.hpp>
17 #include <boost/multi_index/sequenced_index.hpp>
18 #include <boost/multi_index/member.hpp>
19 
20 #include <fstream>
21 #include <list>
22 #include <sstream>
23 #include <queue>
24 
25 namespace aliceVision {
26 namespace image {
27 
28 class TileCacheManager;
29 
38 {
39  public:
40  using weak_pointer = std::weak_ptr<CachedTile>;
41  using smart_pointer = std::shared_ptr<CachedTile>;
42 
43  public:
44  CachedTile() = delete;
45 
46  CachedTile(const std::shared_ptr<TileCacheManager>& manager,
47  size_t uid,
48  size_t tileWidth,
49  size_t tileHeight,
50  size_t width,
51  size_t height,
52  size_t depth)
53  : _manager(manager),
54  _uid(uid),
55  _tileWidth(tileWidth),
56  _tileHeight(tileHeight),
57  _requiredWidth(width),
58  _requiredHeight(height),
59  _depth(depth)
60  {
61  /*Make sure the required size is less or equal than the tile size*/
62  _requiredWidth = std::min(_requiredWidth, _tileWidth);
63  _requiredHeight = std::min(_requiredHeight, _tileHeight);
64  }
65 
66  ~CachedTile();
67 
68  size_t getUid() const { return _uid; }
69 
70  size_t getTileWidth() const { return _tileWidth; }
71 
72  size_t getTileHeight() const { return _tileHeight; }
73 
74  size_t getRequiredWidth() const { return _requiredWidth; }
75 
76  size_t getRequiredHeight() const { return _requiredHeight; }
77 
78  size_t getDepth() const { return _depth; }
79 
80  /*
81  Tells the system that we need the data for this tile.
82  This means that the data is out of core, we want it back.
83  @return false if the process failed to grab data.
84  */
85  bool acquire();
86 
92  void setData(std::unique_ptr<unsigned char>&& data) { _data = std::move(data); }
93 
98  unsigned char* getDataPointer() const
99  {
100  if (!_data)
101  {
102  return nullptr;
103  }
104 
105  return _data.get();
106  }
107 
112  std::unique_ptr<unsigned char> getData() { return std::move(_data); }
113 
114  private:
115  std::unique_ptr<unsigned char> _data = nullptr;
116  std::weak_ptr<TileCacheManager> _manager;
117 
118  size_t _uid;
119  size_t _tileWidth;
120  size_t _tileHeight;
121  size_t _requiredWidth;
122  size_t _requiredHeight;
123  size_t _depth;
124 };
125 
126 /*
127 An abstract concept of cache management for generic objects
128 */
130 {
131  public:
132  using IndexedStoragePaths = std::unordered_map<size_t, std::string>;
133  using IndexedFreeBlocks = std::unordered_map<size_t, std::list<size_t>>;
134 
135  /*
136  An item of the Most Recently used container
137  */
138  struct MRUItem
139  {
140  size_t objectId;
141  size_t objectSize;
142  };
143 
144  /*
145  An item of the object to memory block associative array
146  */
147  struct MemoryItem
148  {
149  size_t startBlockId;
150  size_t countBlock;
151  };
152 
153  using MemoryMap = std::map<size_t, MemoryItem>;
154 
159  using MRUType = boost::multi_index::multi_index_container<
160  MRUItem,
161  boost::multi_index::indexed_by<boost::multi_index::sequenced<>,
162  boost::multi_index::hashed_unique<boost::multi_index::member<MRUItem, size_t, &MRUItem::objectId>>>>;
163 
164  public:
165  CacheManager() = delete;
166 
174  CacheManager(const std::string& pathStorage, size_t blockSize, size_t maxBlocksPerIndex);
175  virtual ~CacheManager();
176 
181  void setMaxMemory(size_t maxMemorySize);
182 
187  void setInCoreMaxObjectCount(size_t max);
188 
195  bool createObject(size_t& objectId, size_t blockCount);
196 
203  bool acquireObject(std::unique_ptr<unsigned char>& data, size_t objectId);
204 
209  size_t getActiveBlocks() const;
210 
211  protected:
212  std::string getPathForIndex(size_t indexId);
213  void deleteIndexFiles();
214  void wipe();
215 
216  bool prepareBlockGroup(size_t startBlockId, size_t blocksCount);
217  std::unique_ptr<unsigned char> load(size_t startBlockId, size_t blocksCount);
218  bool save(std::unique_ptr<unsigned char>&& data, size_t startBlockId, size_t blockCount);
219  bool saveObject(std::unique_ptr<unsigned char>&& data, size_t objectId);
220 
221  virtual void onRemovedFromMRU(size_t objectId) = 0;
222 
223  void addFreeBlock(size_t blockId, size_t blockCount);
224  size_t getFreeBlockId(size_t blockCount);
225 
226  protected:
227  size_t _blockSize{0};
228  size_t _incoreBlockUsageCount{0};
229  size_t _incoreBlockUsageMax{0};
230  size_t _blockCountPerIndex{0};
231  size_t _nextStartBlockId{0};
232  size_t _nextObjectId{0};
233 
234  std::string _basePathStorage;
235  IndexedStoragePaths _indexPaths;
236  IndexedFreeBlocks _freeBlocks;
237 
238  MRUType _mru;
239  MemoryMap _memoryMap;
240 };
241 
246 class TileCacheManager : public CacheManager, public std::enable_shared_from_this<TileCacheManager>
247 {
248  public:
249  using shared_ptr = std::shared_ptr<TileCacheManager>;
250  using MapCachedTile = std::map<size_t, CachedTile::weak_pointer>;
251 
252  public:
253  TileCacheManager() = delete;
254 
264  static std::shared_ptr<TileCacheManager> create(const std::string& pathStorage, size_t tileWidth, size_t tileHeight, size_t maxTilesPerIndex);
265 
271  void notifyDestroy(size_t tileId);
272 
278  bool acquire(size_t tileId);
279 
287  std::shared_ptr<CachedTile> requireNewCachedTile(size_t width, size_t height, size_t blockCount);
288 
289  template<class T>
290  std::shared_ptr<CachedTile> requireNewCachedTile(size_t width, size_t height)
291  {
292  return requireNewCachedTile(width, height, sizeof(T));
293  }
294 
299  size_t getTileWidth() const { return _tileWidth; }
300 
305  size_t getTileHeight() const { return _tileHeight; }
306 
307  protected:
308  TileCacheManager(const std::string& pathStorage, size_t tileWidth, size_t tileHeight, size_t maxTilesPerIndex);
309 
310  virtual void onRemovedFromMRU(size_t objectId);
311 
312  protected:
313  size_t _tileWidth;
314  size_t _tileHeight;
315 
316  MapCachedTile _objectMap;
317 };
318 
319 } // namespace image
320 } // namespace aliceVision
aliceVision::image::CacheManager::MRUType
boost::multi_index::multi_index_container< MRUItem, boost::multi_index::indexed_by< boost::multi_index::sequenced<>, boost::multi_index::hashed_unique< boost::multi_index::member< MRUItem, size_t, &MRUItem::objectId > >> > MRUType
Definition: cache.hpp:162
aliceVision::image::CachedTile::getDataPointer
unsigned char * getDataPointer() const
Definition: cache.hpp:98
aliceVision::image::CacheManager::setMaxMemory
void setMaxMemory(size_t maxMemorySize)
Definition: cache.cpp:34
aliceVision
Definition: checkerDetector.cpp:32
aliceVision::image::CacheManager::getActiveBlocks
size_t getActiveBlocks() const
Definition: cache.cpp:310
aliceVision::image::CacheManager::setInCoreMaxObjectCount
void setInCoreMaxObjectCount(size_t max)
Definition: cache.cpp:36
aliceVision::image::TileCacheManager::requireNewCachedTile
std::shared_ptr< CachedTile > requireNewCachedTile(size_t width, size_t height, size_t blockCount)
Definition: cache.cpp:377
aliceVision::image::TileCacheManager::notifyDestroy
void notifyDestroy(size_t tileId)
Definition: cache.cpp:397
aliceVision::image::CacheManager::acquireObject
bool acquireObject(std::unique_ptr< unsigned char > &data, size_t objectId)
Definition: cache.cpp:223
aliceVision::image::TileCacheManager::acquire
bool acquire(size_t tileId)
Definition: cache.cpp:420
aliceVision::image::TileCacheManager::getTileWidth
size_t getTileWidth() const
Definition: cache.hpp:299
aliceVision::image::CacheManager::MemoryItem
Definition: cache.hpp:147
aliceVision::image::CacheManager
Definition: cache.hpp:129
aliceVision::image::CacheManager::createObject
bool createObject(size_t &objectId, size_t blockCount)
Definition: cache.cpp:210
aliceVision::image::CacheManager::MRUItem
Definition: cache.hpp:138
aliceVision::image::TileCacheManager::getTileHeight
size_t getTileHeight() const
Definition: cache.hpp:305
aliceVision::image::CachedTile
Definition: cache.hpp:37
aliceVision::image::CachedTile::getData
std::unique_ptr< unsigned char > getData()
Definition: cache.hpp:112
aliceVision::image::TileCacheManager::create
static std::shared_ptr< TileCacheManager > create(const std::string &pathStorage, size_t tileWidth, size_t tileHeight, size_t maxTilesPerIndex)
Definition: cache.cpp:357
aliceVision::image::TileCacheManager
Definition: cache.hpp:246
aliceVision::image::CachedTile::setData
void setData(std::unique_ptr< unsigned char > &&data)
Definition: cache.hpp:92