storage.hh
Go to the documentation of this file.
1 
37 #ifndef LibMultiSense_details_storage_hh
38 #define LibMultiSense_details_storage_hh
39 
41 
42 #include <map>
43 #include <deque>
44 
45 namespace crl {
46 namespace multisense {
47 namespace details {
48 
49  //
50  // A message storage interface
51  //
52  // Assumes a 1:1 relationship between template class and ID
53 
54  class MessageMap {
55  public:
56 
57  template<class T> void store(const T& msg) {
59 
60  Map::iterator it = m_map.find(MSG_ID(T::ID));
61  if (m_map.end() != it) {
62  it->second.destroy<T>();
63  m_map.erase(it);
64  }
65 
66  m_map[MSG_ID(T::ID)] = Holder::Create<T>(msg);
67  }
68 
69  template<class T> Status extract(T& msg) {
71 
72  Map::iterator it = m_map.find(MSG_ID(T::ID));
73  if (m_map.end() == it)
74  return Status_Error;
75 
76  it->second.extract(msg);
77  m_map.erase(it);
78 
79  return Status_Ok;
80  }
81 
82  private:
83 
84  class Holder {
85  public:
86 
87  Holder(void *r=NULL) : m_refP(r) {};
88 
89  template<class T> static Holder Create(const T& msg) {
90  return Holder(reinterpret_cast<void *>(new T(msg)));
91  }
92 
93  template<class T> void destroy() {
94  if (NULL == m_refP)
95  CRL_EXCEPTION("destroying NULL reference", "");
96  delete reinterpret_cast<T*>(m_refP);
97  }
98 
99  template<class T> void extract(T& msg) {
100  if (NULL == m_refP)
101  CRL_EXCEPTION("extracting NULL reference", "");
102  msg = *(reinterpret_cast<T*>(m_refP));
103  destroy<T>();
104  }
105 
106  private:
107  void *m_refP;
108  };
109 
110  typedef std::map<wire::IdType, Holder> Map;
111 
113  Map m_map;
114  };
115 
116  //
117  // A constant-depth cache.
118  //
119  // Up to [depth] entries will be cached. Oldest entries
120  // will be dropped on insertion once full.
121  //
122  // The age of an entry is determined by std::map<KEY,DATA>.lower_bound([min]).
123  //
124  // DATA objects are assumed to be allocated on the heap, and memory management
125  // of the object is delegated here upon insert().
126  //
127  // For *_nolock() variations, lock-management must be
128  // done by the user.
129 
130  template<class KEY, class DATA>
131  class DepthCache {
132  public:
133 
134  DepthCache(std::size_t depth) :
135  m_depth(depth) {};
136 
139 
140  typename MapType::iterator it = m_map.begin();
141  for(; it != m_map.end();) {
142  delete it->second;
143  m_map.erase(it++);
144  }
145  };
146 
148  return m_lock;
149  };
150 
151  DATA* find_nolock(KEY key) {
152  return find_(key);
153  };
154 
155  DATA* find(KEY key) {
157  return find_(key);
158  };
159 
160  void insert_nolock(KEY key, DATA* data) {
161  insert_(key, data);
162  };
163 
164  void insert(KEY key, DATA* data) {
166  insert_(key, data);
167  };
168 
169  void remove_nolock(KEY key) {
170  remove_(key);
171  };
172 
173  void remove(KEY key) {
175  remove_(key);
176  };
177 
178  private:
179 
180  typedef std::deque<KEY> QueueType;
181  typedef std::map<KEY,DATA*> MapType;
182 
183  DATA* find_(KEY key) {
184  typename MapType::iterator it = m_map.find(key);
185 
186  if (m_map.end() == it)
187  return NULL;
188  else
189  return it->second;
190  };
191 
192  void insert_(KEY key, DATA* data) {
193  if (m_map.size() == m_depth)
194  {
195  pop_oldest_();
196  }
197 
198  typename MapType::iterator it = m_map.find(key);
199  if (it == m_map.end()) {
200  m_queue.push_front(key);
201  m_map[key] = data;
202  }
203  else {
204  delete it->second;
205  it->second = data;
206  }
207 
208  };
209 
210  void remove_(KEY key) {
211  typename MapType::iterator it2 = m_map.find(key);
212  if (m_map.end() != it2) {
213  delete it2->second;
214  m_map.erase(it2);
215  }
216 
217  //assume we're erasing an older key, so search the order queue from the back
218  for (typename QueueType::reverse_iterator it = m_queue.rbegin(); it != m_queue.rend();) {
219  if (*it == key) {
220  m_queue.erase(--(it.base()));
221  break;
222  }
223  ++it;
224  }
225  };
226 
227  void pop_oldest_() {
228 
229  while (!m_queue.empty())
230  {
231  KEY k = m_queue.back();
232  typename MapType::iterator it2 = m_map.find(k);
233  if (m_map.end() != it2) {
234  delete it2->second;
235  m_map.erase(it2);
236  m_queue.pop_back();
237  break;
238  }
239  m_queue.pop_back();
240  }
241  };
242 
243  const std::size_t m_depth;
244  MapType m_map;
245  QueueType m_queue;
247  };
248 
249 }}} // namespaces
250 
251 #endif // LibMultiSense_details_storage_hh
#define CRL_EXCEPTION(fmt,...)
Definition: Exception.hh:85
void insert(KEY key, DATA *data)
Definition: storage.hh:164
std::map< KEY, DATA * > MapType
Definition: storage.hh:181
void insert_nolock(KEY key, DATA *data)
Definition: storage.hh:160
Definition: channel.cc:58
#define MSG_ID(x)
Definition: Protocol.hh:311
static CRL_CONSTEXPR Status Status_Ok
void insert_(KEY key, DATA *data)
Definition: storage.hh:192
std::map< wire::IdType, Holder > Map
Definition: storage.hh:110
static Holder Create(const T &msg)
Definition: storage.hh:89
static CRL_CONSTEXPR Status Status_Error


multisense_lib
Author(s):
autogenerated on Sat Jun 24 2023 03:01:21