Go to the documentation of this file.00001
00037 #ifndef LibMultiSense_details_storage_hh
00038 #define LibMultiSense_details_storage_hh
00039
00040 #include "details/utility/Thread.hh"
00041
00042 #include <map>
00043 #include <set>
00044
00045 namespace crl {
00046 namespace multisense {
00047 namespace details {
00048
00049
00050
00051
00052
00053
00054 class MessageMap {
00055 public:
00056
00057 template<class T> void store(const T& msg) {
00058 utility::ScopedLock lock(m_lock);
00059
00060 Map::iterator it = m_map.find(MSG_ID(T::ID));
00061 if (m_map.end() != it) {
00062 it->second.destroy<T>();
00063 m_map.erase(it);
00064 }
00065
00066 m_map[MSG_ID(T::ID)] = Holder::Create<T>(msg);
00067 };
00068
00069 template<class T> Status extract(T& msg) {
00070 utility::ScopedLock lock(m_lock);
00071
00072 Map::iterator it = m_map.find(MSG_ID(T::ID));
00073 if (m_map.end() == it)
00074 return Status_Error;
00075
00076 it->second.extract(msg);
00077 m_map.erase(it);
00078
00079 return Status_Ok;
00080 };
00081
00082 private:
00083
00084 class Holder {
00085 public:
00086
00087 Holder(void *r=NULL) : m_refP(r) {};
00088
00089 template<class T> static Holder Create(const T& msg) {
00090 return Holder(reinterpret_cast<void *>(new T(msg)));
00091 };
00092
00093 template<class T> void destroy() {
00094 if (NULL == m_refP)
00095 CRL_EXCEPTION("destroying NULL reference");
00096 delete reinterpret_cast<T*>(m_refP);
00097 };
00098
00099 template<class T> void extract(T& msg) {
00100 if (NULL == m_refP)
00101 CRL_EXCEPTION("extracting NULL reference");
00102 msg = *(reinterpret_cast<T*>(m_refP));
00103 destroy<T>();
00104 };
00105
00106 private:
00107 void *m_refP;
00108 };
00109
00110 typedef std::map<wire::IdType, Holder> Map;
00111
00112 utility::Mutex m_lock;
00113 Map m_map;
00114 };
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 template<class KEY, class DATA>
00131 class DepthCache {
00132 public:
00133
00134 DepthCache(std::size_t depth, KEY min) :
00135 m_depth(depth),
00136 m_minimum(min) {};
00137
00138 ~DepthCache() {
00139 utility::ScopedLock lock(m_lock);
00140
00141 typename MapType::iterator it = m_map.begin();
00142 for(; it != m_map.end();) {
00143 delete it->second;
00144 m_map.erase(it++);
00145 }
00146 };
00147
00148 utility::Mutex& mutex() {
00149 return m_lock;
00150 };
00151
00152 DATA* find_nolock(KEY key) {
00153 return find_(key);
00154 };
00155
00156 DATA* find(KEY key) {
00157 utility::ScopedLock lock(m_lock);
00158 return find_(key);
00159 };
00160
00161 void insert_nolock(KEY key, DATA* data) {
00162 insert_(key, data);
00163 };
00164
00165 void insert(KEY key, DATA* data) {
00166 utility::ScopedLock lock(m_lock);
00167 insert_(key, data);
00168 };
00169
00170 void remove_nolock(KEY key) {
00171 remove_(key);
00172 };
00173
00174 void remove(KEY key) {
00175 utility::ScopedLock lock(m_lock);
00176 remove_(key);
00177 };
00178
00179 private:
00180
00181 typedef std::map<KEY,DATA*> MapType;
00182
00183 DATA* find_(KEY key) {
00184 typename MapType::iterator it = m_map.find(key);
00185
00186 if (m_map.end() == it)
00187 return NULL;
00188 else
00189 return it->second;
00190 };
00191
00192 void insert_(KEY key, DATA* data) {
00193 if (m_map.size() == m_depth)
00194 pop_oldest_();
00195
00196 m_map[key] = data;
00197 };
00198
00199 void remove_(KEY key) {
00200 typename MapType::iterator it2 = m_map.find(key);
00201 if (m_map.end() != it2) {
00202 delete it2->second;
00203 m_map.erase(it2);
00204 }
00205 };
00206
00207 void pop_oldest_() {
00208 typename MapType::iterator it2 = m_map.lower_bound(m_minimum);
00209 if (m_map.end() != it2) {
00210 delete it2->second;
00211 m_map.erase(it2);
00212 }
00213 };
00214
00215 const std::size_t m_depth;
00216 const KEY m_minimum;
00217
00218 MapType m_map;
00219 utility::Mutex m_lock;
00220 };
00221
00222 }}};
00223
00224 #endif // LibMultiSense_details_storage_hh