1 #ifndef TrackingTools_TrajectoryCleaning_src_OtherHashMaps
2 #define TrackingTools_TrajectoryCleaning_src_OtherHashMaps
9 #include <boost/unordered_map.hpp>
10 #include <boost/range.hpp>
11 #include <boost/type_traits.hpp>
12 #include <boost/mpl/and.hpp>
13 #include <boost/mpl/logical.hpp>
14 #include <boost/mpl/assert.hpp>
15 #include <boost/mpl/if.hpp>
32 typename Hasher = boost::hash<K>,
33 typename Equals = std::equal_to<K>,
34 typename Alloc = std::allocator<V> >
37 BOOST_MPL_ASSERT((boost::mpl::and_<boost::has_trivial_destructor<K>, boost::has_trivial_destructor<V> >));
42 typedef typename boost::mpl::if_<typename boost::is_pointer<V>,
V,
V const &>
::type
49 void clear(
size_t newBucketSize = 0) {
50 if (newBucketSize != 0) {
91 template <
typename Item>
112 bool good()
const {
return (
it_ !=
nullptr); }
132 typename std::list<KeyItem *>::iterator
138 typename std::list<ValueItem *>::iterator
155 std::cout <<
"Dumping HASH MULTIMAP" << std::endl;
166 std::cout <<
" [" << row <<
"] " << *
p << std::endl;
175 std::cout <<
" @ " <<
p <<
" [" <<
p->key <<
", @" <<
p->value <<
"], next = " <<
p->next << std::endl;
177 std::cout <<
" ^^^ this was the last valid item." << std::endl;
186 std::cout <<
" Value Items " << std::endl;
192 std::cout <<
" @ " <<
p <<
" [" <<
p->value <<
"], next = " <<
p->next << std::endl;
194 std::cout <<
" ^^^ this was the last valid item." << std::endl;
202 std::cout <<
" End of dump" << std::endl;
206 template <
typename K,
typename V,
typename Hasher,
typename Equals,
typename Alloc>
211 : bucketSize_(buckets),
212 bucketCapacity_(bucketSize_),
213 keyRowSize_(keyRowSize),
214 valueRowSize_(valueRowSize),
221 template <
typename K,
typename V,
typename Hasher,
typename Equals,
typename Alloc>
223 for (
typename std::list<KeyItem *>::iterator it = keyRows_.begin(),
last = keyRows_.end(); it !=
last; ++it) {
224 keyAlloc_.deallocate(*it, keyRowSize_);
226 for (
typename std::list<ValueItem *>::iterator it = valueRows_.begin(),
last = valueRows_.end(); it !=
last; ++it) {
227 valueAlloc_.deallocate(*it, valueRowSize_);
229 ptrAlloc_.deallocate(buckets_, bucketCapacity_);
232 template <
typename K,
typename V,
typename Hasher,
typename Equals,
typename Alloc>
234 if (keyRows_.size() > maxRows_) {
236 typename std::list<KeyItem *>::iterator it = keyRows_.begin(),
last = keyRows_.end();
237 for (std::advance(it, maxRows_); it !=
last; ++it) {
238 keyAlloc_.deallocate(*it, keyRowSize_);
240 keyRows_.resize(maxRows_);
242 if (valueRows_.size() > maxRows_) {
244 typename std::list<ValueItem *>::iterator it = valueRows_.begin(),
last = valueRows_.end();
245 for (std::advance(it, maxRows_); it !=
last; ++it) {
246 valueAlloc_.deallocate(*it, valueRowSize_);
248 valueRows_.resize(maxRows_);
252 template <
typename K,
typename V,
typename Hasher,
typename Equals,
typename Alloc>
255 if (nextKeyItem_ == keyEndMarker_) {
257 if (currentKeyRow_ == keyRows_.end()) {
258 keyRows_.push_back(keyAlloc_.allocate(keyRowSize_));
259 currentKeyRow_ = keyRows_.end();
262 nextKeyItem_ = *currentKeyRow_;
263 keyEndMarker_ = nextKeyItem_ + keyRowSize_;
267 return (nextKeyItem_ - 1);
269 template <
typename K,
typename V,
typename Hasher,
typename Equals,
typename Alloc>
272 if (nextValueItem_ == valueEndMarker_) {
274 if (currentValueRow_ == valueRows_.end()) {
275 valueRows_.push_back(valueAlloc_.allocate(valueRowSize_));
276 currentValueRow_ = valueRows_.end();
279 nextValueItem_ = *currentValueRow_;
280 valueEndMarker_ = nextValueItem_ + valueRowSize_;
284 return (nextValueItem_ - 1);
287 template <
typename K,
typename V,
typename Hasher,
typename Equals,
typename Alloc>
295 if (eq_(curr->
key,
key)) {
301 buck = push_back_(
key, buck);
305 template <
typename K,
typename V,
typename Hasher,
typename Equals,
typename Alloc>
310 k.value = push_back_(
value,
k.value);
313 template <
typename K,
typename V,
typename Hasher,
typename Equals,
typename Alloc>
318 for (
KeyItem *curr = buckets_[
hash % bucketSize_]; curr; curr = curr->
next) {
319 if (eq_(curr->key,
key))
330 template <
typename K,
typename V>
335 typedef typename std::vector<value_type>::iterator
iterator;
345 for (
typename std::vector<value_type>::iterator it =
data_.begin(), ed =
data_.end(); it != ed; ++it) {
350 return data_.back().second;