iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IdTableImpl.H
Go to the documentation of this file.
1 /*! @file
2  @author Randolph Voorhies
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 
36 #ifndef INCLUDE_NRT_CORE_DESIGN_DETAILS_IDTABLEIMPL_H
37 #define INCLUDE_NRT_CORE_DESIGN_DETAILS_IDTABLEIMPL_H
38 
40 
41 template<class ValueType, class IdType>
42 class nrt::IdTable<ValueType, IdType>::IdNotFoundException : public nrt::exception::Exception
43 {
44  public:
45  IdNotFoundException(IdType const & id) throw()
46  try : nrt::exception::Exception("Error IdNotFoundException, and further error while constructing the exception"),
47  itsId(id)
48  { whatptr = "Invalid Reverse Lookup"; } catch (...) { }
49 
50  virtual ~IdNotFoundException() throw() { }
51 
52  IdType itsId;
53 };
54 
55 template<class ValueType, class IdType>
56 class nrt::IdTable<ValueType, IdType>::ValueNotFoundException : public nrt::exception::Exception
57 {
58  public:
59  ValueNotFoundException(ValueType const & value) throw()
60  try : nrt::exception::Exception("Error ValueNotFoundException, and further error while constructing the exception"),
61  itsValue(value)
62  { whatptr = "Invalid Forward Lookup"; } catch (...) { }
63 
64  virtual ~ValueNotFoundException() throw() { }
65 
66  ValueType itsValue;
67 };
68 
69 
70 // ######################################################################
71 template<class ValueType, class IdType> inline
73  : itsMaxId(0)
74 { }
75 
76 // ######################################################################
77 template<class ValueType, class IdType> inline
78 IdType nrt::IdTable<ValueType, IdType>::create(ValueType const & value)
79 {
80  auto itr = itsValueIdMap.find(value);
81 
82  if (itr == itsValueIdMap.end()) {
83  return create_internal(value);
84  } else {
85  // increment user count and return it:
86  typename std::unordered_map<IdType, ValueData>::iterator idItr = itsIdValueMap.find(itr->second);
87  ++ idItr->second.second;
88  return idItr->first;
89  }
90 }
91 
92 // ######################################################################
93 template<class ValueType, class IdType> inline
94 ValueType nrt::IdTable<ValueType, IdType>::get(IdType const & id) const
95 {
96  auto itr = itsIdValueMap.find(id);
97  if (itr == itsIdValueMap.end()) throw IdNotFoundException(id);
98 
99  return itr->second.first;
100 }
101 
102 // ######################################################################
103 template<class ValueType, class IdType> inline
104 IdType nrt::IdTable<ValueType, IdType>::get(ValueType const & value) const
105 {
106  auto itr = itsValueIdMap.find(value);
107  if (itr == itsValueIdMap.end()) throw ValueNotFoundException(value);
108 
109  return itr->second;
110 }
111 
112 // ######################################################################
113 template<class ValueType, class IdType> inline
114 IdType nrt::IdTable<ValueType, IdType>::getcreate(ValueType const & value)
115 {
116  auto itr = itsValueIdMap.find(value);
117  if (itr == itsValueIdMap.end()) return create_internal(value);
118  else return itr->second;
119 }
120 
121 // ######################################################################
122 template<class ValueType, class IdType> inline
123 size_t nrt::IdTable<ValueType, IdType>::users(ValueType const & value) const
124 {
125  auto itr = itsValueIdMap.find(value);
126  if (itr == itsValueIdMap.end()) return 0;
127  else return users(itr->second);
128 }
129 
130 // ######################################################################
131 template<class ValueType, class IdType> inline
132 size_t nrt::IdTable<ValueType, IdType>::users(IdType const & id) const
133 {
134  auto itr = itsIdValueMap.find(id);
135  if (itr == itsIdValueMap.end()) return 0;
136  else return itr->second.second;
137 }
138 
139 // ######################################################################
140 template<class ValueType, class IdType>
142 {
143  auto idItr = itsIdValueMap.find(id);
144  if (idItr == itsIdValueMap.end()) throw IdNotFoundException(id);
145 
146  // decrement user count:
147  -- idItr->second.second;
148 
149  // delete the id if count down to zero:
150  if (idItr->second.second == 0) {
151  auto valueItr = itsValueIdMap.find(idItr->second.first);
152 
153  itsRecycleBin.push(id);
154 
155  itsIdValueMap.erase(idItr);
156  itsValueIdMap.erase(valueItr);
157 
158  return 0;
159  } else return idItr->second.second;
160 }
161 
162 // ######################################################################
163 template<class ValueType, class IdType>
164 size_t nrt::IdTable<ValueType, IdType>::remove(ValueType const & value)
165 {
166  auto valueItr = itsValueIdMap.find(value);
167  if (valueItr == itsValueIdMap.end()) throw ValueNotFoundException(value);
168 
169  auto idItr = itsIdValueMap.find(valueItr->second);
170 
171  // decrement user count:
172  -- idItr->second.second;
173 
174  // delete the id if count down to zero:
175  if (idItr->second.second == 0) {
176  itsRecycleBin.push(valueItr->second);
177 
178  itsIdValueMap.erase(idItr);
179  itsValueIdMap.erase(valueItr);
180 
181  return 0;
182  } else return idItr->second.second;
183 }
184 
185 // ######################################################################
186 template<class ValueType, class IdType>
188 {
189  itsIdValueMap.clear();
190  itsValueIdMap.clear();
191  itsRecycleBin = std::queue<IdType>();
192  itsMaxId = IdType();
193 }
194 
195 // ######################################################################
196 template<class ValueType, class IdType> inline
197 IdType nrt::IdTable<ValueType, IdType>::create_internal(ValueType const & value)
198 {
199  // Recycle an old id, or generate a new one
200  IdType id;
201  if (itsRecycleBin.size()) { id = itsRecycleBin.front(); itsRecycleBin.pop(); }
202  else { id = ++itsMaxId; }
203 
204  itsValueIdMap[value] = id;
205  itsIdValueMap[id] = std::pair<ValueType, size_t>(value, size_t(1));
206 
207  return id;
208 }
209 
210 #endif // INCLUDE_NRT_CORE_DESIGN_DETAILS_IDTABLEIMPL_H