STXXL  1.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
iterator_map.h
Go to the documentation of this file.
1 /***************************************************************************
2  * include/stxxl/bits/containers/hash_map/iterator_map.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2007 Markus Westphal <[email protected]>
7  * Copyright (C) 2014 Timo Bingmann <[email protected]>
8  *
9  * Distributed under the Boost Software License, Version 1.0.
10  * (See accompanying file LICENSE_1_0.txt or copy at
11  * http://www.boost.org/LICENSE_1_0.txt)
12  **************************************************************************/
13 
14 #ifndef STXXL_CONTAINERS_HASH_MAP_ITERATOR_MAP_HEADER
15 #define STXXL_CONTAINERS_HASH_MAP_ITERATOR_MAP_HEADER
16 
17 #include <map>
18 
19 #include <stxxl/bits/noncopyable.h>
22 
24 
25 namespace hash_map {
26 
27 template <class HashMap>
28 class iterator_map : private noncopyable
29 {
30 public:
31  typedef HashMap hash_map_type;
32  typedef typename hash_map_type::node_type node_type;
33  typedef typename hash_map_type::source_type source_type;
34  typedef typename hash_map_type::key_type key_type;
35 
38 
40 
41 private:
42 #if 0
43  typedef std::multimap<internal_size_type, iterator_base*> multimap_type;
44 #else
45  struct hasher
46  {
47  size_t operator () (const internal_size_type& key) const
48  {
49  return longhash1(key);
50  }
51 #if STXXL_MSVC
52  bool operator () (const internal_size_type& a, const internal_size_type& b) const
53  {
54  return (a < b);
55  }
56  enum
57  { // parameters for hash table
58  bucket_size = 4, // 0 < bucket_size
59  min_buckets = 8 // min_buckets = 2 ^^ N, 0 < N
60  };
61 #endif
62  };
63  // store iterators by bucket-index
64  typedef typename compat_hash_multimap<
65  internal_size_type, iterator_base*, hasher
66  >::result multimap_type;
67 #endif
68 
69  //! bucket-index and pointer to iterator_base
70  typedef typename multimap_type::value_type pair_type;
71  typedef typename multimap_type::iterator mmiterator_type;
72  typedef typename multimap_type::const_iterator const_mmiterator_type;
73 
74  hash_map_type* map_;
76 
77 public:
78  iterator_map(hash_map_type* map)
79  : map_(map)
80  { }
81 
83  {
84  it_map_.clear();
85  }
86 
88  {
89  register_iterator(it, it.i_bucket_);
90  }
91 
93  {
94  STXXL_VERBOSE2("hash_map::iterator_map register_iterator addr=" << &it << " bucket=" << i_bucket);
95  it_map_.insert(pair_type(i_bucket, &it));
96  }
97 
99  {
100  unregister_iterator(it, it.i_bucket_);
101  }
102 
104  {
105  STXXL_VERBOSE2("hash_map::iterator_map unregister_iterator addr=" << &it << " bucket=" << i_bucket);
106 
107  std::pair<mmiterator_type, mmiterator_type> range
108  = it_map_.equal_range(i_bucket);
109 
110  assert(range.first != range.second);
111 
112  for (mmiterator_type i = range.first; i != range.second; ++i)
113  {
114  if (i->second == &it)
115  {
116  it_map_.erase(i);
117  return;
118  }
119  }
120 
121  throw std::runtime_error("unregister_iterator Panic in hash_map::iterator_map, can not find and unregister iterator");
122  }
123 
124  //! Update iterators with given key and bucket and make them point to the
125  //! specified location in external memory (will be called during
126  //! re-hashing)
127  void fix_iterators_2ext(internal_size_type i_bucket_old, const key_type& key,
128  internal_size_type i_bucket_new, external_size_type i_ext)
129  {
130  STXXL_VERBOSE2("hash_map::iterator_map fix_iterators_2ext i_bucket=" << i_bucket_old << " new_i_ext=" << i_ext);
131 
132  std::vector<iterator_base*> its2fix;
133  _find(i_bucket_old, its2fix);
134 
135  for (typename std::vector<iterator_base*>::iterator
136  it2fix = its2fix.begin(); it2fix != its2fix.end(); ++it2fix)
137  {
138  if (!map_->_eq(key, (**it2fix).key_))
139  continue;
140 
141  if (i_bucket_old != i_bucket_new)
142  {
143  unregister_iterator(**it2fix);
144  register_iterator(**it2fix, i_bucket_new);
145  }
146 
147  (**it2fix).i_bucket_ = i_bucket_new;
148  (**it2fix).node_ = NULL;
149  (**it2fix).i_external_ = i_ext;
150  (**it2fix).source_ = hash_map_type::src_external;
151  // external position is now known (i_ext) and therefore valid
152  (**it2fix).ext_valid_ = true;
153  (**it2fix).reset_reader();
154  (**it2fix).reader_ = NULL;
155  }
156  }
157 
158  //! Update iterators with given key and bucket and make them point to the
159  //! specified node in internal memory (will be called by insert_oblivious)
161  {
162  STXXL_VERBOSE2("hash_map::iterator_map fix_iterators_2int i_bucket=" << i_bucket << " node=" << node);
163 
164  std::vector<iterator_base*> its2fix;
165  _find(i_bucket, its2fix);
166 
167  for (typename std::vector<iterator_base*>::iterator
168  it2fix = its2fix.begin(); it2fix != its2fix.end(); ++it2fix)
169  {
170  if (!map_->_eq((**it2fix).key_, key))
171  continue;
172 
173  assert((**it2fix).source_ == hash_map_type::src_external);
174 
175  (**it2fix).source_ = hash_map_type::src_internal;
176  (**it2fix).node_ = node;
177  (**it2fix).i_external_++;
178  if ((** it2fix).reader_)
179  (** it2fix).reader_->operator ++ ();
180  }
181  }
182 
183  //! Update iterators with given key and bucket and make them point to the
184  //! end of the hash-map (called by erase and erase_oblivious)
185  void fix_iterators_2end(internal_size_type i_bucket, const key_type& key)
186  {
187  STXXL_VERBOSE2("hash_map::iterator_map fix_iterators_2end i_bucket=" << i_bucket);
188 
189  std::vector<iterator_base*> its2fix;
190  _find(i_bucket, its2fix);
191 
192  for (typename std::vector<iterator_base*>::iterator
193  it2fix = its2fix.begin(); it2fix != its2fix.end(); ++it2fix)
194  {
195  if (!map_->_eq(key, (**it2fix).key_))
196  continue;
197 
198  (**it2fix).end_ = true;
199  (**it2fix).reset_reader();
200  unregister_iterator(**it2fix);
201  }
202  }
203 
204  //! Update all iterators and make them point to the end of the hash-map
205  //! (used by clear())
207  {
208  for (mmiterator_type it2fix = it_map_.begin();
209  it2fix != it_map_.end(); ++it2fix)
210  {
211  (*it2fix).second->end_ = true;
212  (*it2fix).second->reset_reader();
213  }
214  it_map_.clear();
215  }
216 
217 private:
218  //! Find all iterators registered with given bucket and add them to outc
219  template <class OutputContainer>
220  void _find(internal_size_type i_bucket, OutputContainer& outc)
221  {
222  std::pair<mmiterator_type, mmiterator_type> range
223  = it_map_.equal_range(i_bucket);
224 
225  for (mmiterator_type i = range.first; i != range.second; ++i)
226  outc.push_back((*i).second);
227  }
228 
229  // changes hash_map pointer in all contained iterators
230  void change_hash_map_pointers(hash_map_type* map)
231  {
232  for (mmiterator_type it = it_map_.begin(); it != it_map_.end(); ++it)
233  ((*it).second)->map_ = map;
234  }
235 
236 public:
238  {
239  std::swap(it_map_, obj.it_map_);
240  std::swap(map_, obj.map_);
241 
242  change_hash_map_pointers(map_);
243  obj.change_hash_map_pointers(obj.map_);
244  }
245 
246  void print_statistics(std::ostream& o = std::cout) const
247  {
248  o << "Registered iterators: " << it_map_.size() << "\n";
249 
250  for (const_mmiterator_type i = it_map_.begin(); i != it_map_.end(); ++i)
251  {
252  o << " Address=" << i->second
253  << ", Bucket=" << i->second->i_bucket_
254  << ", Node=" << i->second->node_
255  << ", i_ext=" << i->second->i_external_
256  << ", "
257  << ((i->second->source_ == hash_map_type::src_external)
258  ? "external" : "internal") << std::endl;
259  }
260  }
261 };
262 
263 } // namespace hash_map
264 
266 
267 namespace std {
268 
269 template <class HashMapType>
272 {
273  if (&a != &b)
274  a.swap(b);
275 }
276 
277 } // namespace std
278 
279 #endif // !STXXL_CONTAINERS_HASH_MAP_ITERATOR_MAP_HEADER
multimap_type::iterator mmiterator_type
Definition: iterator_map.h:71
multimap_type::value_type pair_type
Definition: iterator_map.h:65
void fix_iterators_all2end()
Update all iterators and make them point to the end of the hash-map (used by clear()) ...
Definition: iterator_map.h:206
void print_statistics(std::ostream &o=std::cout) const
Definition: iterator_map.h:246
size_t longhash1(uint64 key_)
Definition: utils.h:230
multimap_type::const_iterator const_mmiterator_type
Definition: iterator_map.h:72
compat_hash_multimap< internal_size_type, iterator_base *, hasher >::result multimap_type
Definition: iterator_map.h:66
hash_map_iterator_base< hash_map_type > iterator_base
Definition: iterator_map.h:39
void fix_iterators_2ext(internal_size_type i_bucket_old, const key_type &key, internal_size_type i_bucket_new, external_size_type i_ext)
Update iterators with given key and bucket and make them point to the specified location in external ...
Definition: iterator_map.h:127
#define STXXL_VERBOSE2(x)
Definition: verbose.h:107
iterator_map(hash_map_type *map)
Definition: iterator_map.h:78
void fix_iterators_2int(internal_size_type i_bucket, const key_type &key, node_type *node)
Update iterators with given key and bucket and make them point to the specified node in internal memo...
Definition: iterator_map.h:160
hash_map_type::external_size_type external_size_type
Definition: iterator_map.h:37
void _find(internal_size_type i_bucket, OutputContainer &outc)
Find all iterators registered with given bucket and add them to outc.
Definition: iterator_map.h:220
void change_hash_map_pointers(hash_map_type *map)
Definition: iterator_map.h:230
unsigned_type internal_size_type
Definition: types.h:66
multimap_type::iterator mmiterator_type
Definition: iterator_map.h:66
void unregister_iterator(iterator_base &it, internal_size_type i_bucket)
Definition: iterator_map.h:103
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
void register_iterator(iterator_base &it)
Definition: iterator_map.h:87
std::multimap< Key, iterator_base *, KeyCmp > multimap_type
Definition: iterator_map.h:60
void unregister_iterator(iterator_base &it)
Definition: iterator_map.h:98
void swap(iterator_map< HashMap > &obj)
Definition: iterator_map.h:237
hash_map_type::internal_size_type internal_size_type
Definition: iterator_map.h:36
uint64 external_size_type
Definition: types.h:67
void register_iterator(iterator_base &it, internal_size_type i_bucket)
Definition: iterator_map.h:92
External associative container (map). Introduction to map container: see STXXL Map (B+-tree) tutor...
Definition: map.h:82
multimap_type::value_type pair_type
bucket-index and pointer to iterator_base
Definition: iterator_map.h:70
hash_map_type::key_type key_type
Definition: iterator_map.h:34
hash_map_type::node_type node_type
Definition: iterator_map.h:32
hash_map_type::source_type source_type
Definition: iterator_map.h:33
#define STXXL_END_NAMESPACE
Definition: namespace.h:17
void fix_iterators_2end(internal_size_type i_bucket, const key_type &key)
Update iterators with given key and bucket and make them point to the end of the hash-map (called by ...
Definition: iterator_map.h:185