DASH  0.3.0
UnorderedMapLocalRef.h
1 #ifndef DASH__MAP__UNORDERED_MAP_LOCAL_REF_H__INCLUDED
2 #define DASH__MAP__UNORDERED_MAP_LOCAL_REF_H__INCLUDED
3 
4 #include <dash/Team.h>
5 
6 namespace dash {
7 
8 #ifdef DOXYGEN
9 
10 
19 template<
20  typename Key,
21  typename Mapped,
22  typename Hash,
23  typename Pred,
24  typename LMemSpace >
26 
27 #else // ifdef DOXYGEN
28 
29 // Forward-declaration.
30 template<
31  typename Key,
32  typename Mapped,
33  typename Hash,
34  typename Pred,
35  typename LMemSpace >
36 class UnorderedMap;
37 
38 template<
39  typename Key,
40  typename Mapped,
41  typename Hash,
42  typename Pred,
43  typename LMemSpace >
45 {
46 private:
48  self_t;
49 
51  map_type;
52 
53 public:
54  typedef Key key_type;
55  typedef Mapped mapped_type;
56  typedef Hash hasher;
57  typedef Pred key_equal;
58 
59  typedef typename map_type::index_type index_type;
60  typedef typename map_type::difference_type difference_type;
61  typedef typename map_type::size_type size_type;
62  typedef typename map_type::value_type value_type;
63 
64  typedef self_t local_type;
65 
66  typedef typename map_type::glob_mem_type glob_mem_type;
67 
68  typedef typename map_type::local_node_pointer node_pointer;
69  typedef typename map_type::local_node_pointer local_node_pointer;
70 
71  typedef typename map_type::local_iterator iterator;
72  typedef typename map_type::const_local_iterator const_iterator;
73  typedef typename map_type::reverse_local_iterator
74  reverse_iterator;
75  typedef typename map_type::const_reverse_local_iterator
76  const_reverse_iterator;
77 
78  typedef typename map_type::local_iterator local_iterator;
79  typedef typename map_type::const_local_iterator const_local_iterator;
80  typedef typename map_type::reverse_local_iterator
81  reverse_local_iterator;
82  typedef typename map_type::const_reverse_local_iterator
83  const_reverse_local_iterator;
84 
85  typedef typename map_type::local_reference reference;
86  typedef typename map_type::const_local_reference const_reference;
87  typedef typename map_type::local_reference local_reference;
88  typedef typename map_type::const_local_reference const_local_reference;
89 
90  typedef typename map_type::mapped_type_reference
91  mapped_type_reference;
92  typedef typename map_type::const_mapped_type_reference
93  const_mapped_type_reference;
94 
95 private:
96  map_type * _map = nullptr;
97 
98 public:
100  // Pointer to instance of \c dash::UnorderedMap referenced by the view
101  // specifier.
102  map_type * map)
103  : _map(map)
104  { }
105 
106  UnorderedMapLocalRef() = default;
107 
109  // Distributed container
111 
112  inline dash::Team & team() const noexcept
113  {
114  return _map->team();
115  }
116 
117  inline const glob_mem_type & globmem() const
118  {
119  return _map->globmem();
120  }
121 
123  // Iterators
125 
126  inline iterator & begin() noexcept
127  {
128  return _map->lbegin();
129  }
130 
131  inline const_iterator & begin() const noexcept
132  {
133  return _map->lbegin();
134  }
135 
136  inline const_iterator & cbegin() const noexcept
137  {
138  return _map->clbegin();
139  }
140 
141  inline iterator & end() noexcept
142  {
143  return _map->lend();
144  }
145 
146  inline const_iterator & end() const noexcept
147  {
148  return _map->lend();
149  }
150 
151  inline const_iterator & cend() const noexcept
152  {
153  return _map->clend();
154  }
155 
157  // Capacity
159 
160  constexpr size_type max_size() const noexcept
161  {
162  return _map->max_size();
163  }
164 
165  inline size_type size() const noexcept
166  {
167  return _map->lsize();
168  }
169 
170  inline size_type capacity() const noexcept
171  {
172  return _map->lcapacity();
173  }
174 
175  inline bool empty() const noexcept
176  {
177  return _map->lsize() == 0;
178  }
179 
180  inline size_type lsize() const noexcept
181  {
182  return _map->lsize();
183  }
184 
185  inline size_type lcapacity() const noexcept
186  {
187  return _map->lcapacity();
188  }
189 
191  // Element Access
193 
194  mapped_type_reference operator[](const key_type & key)
195  {
196  DASH_LOG_TRACE("UnorderedMapLocalRef.[]()", "key:", key);
197  iterator git_value = insert(
198  std::make_pair(key, mapped_type()))
199  .first;
200  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.[]", git_value);
201  dart_gptr_t gptr_mapped = git_value.dart_gptr();
202  value_type * lptr_value = git_value.local();
203  mapped_type * lptr_mapped = nullptr;
204 
205  _lptr_value_to_mapped(lptr_value, gptr_mapped, lptr_mapped);
206  // Create global reference to mapped value member in element:
207  mapped_type_reference mapped(gptr_mapped,
208  lptr_mapped);
209  DASH_LOG_TRACE("UnorderedMapLocalRef.[] >", mapped);
210  return mapped;
211  }
212 
213  const_mapped_type_reference at(const key_type & key) const
214  {
215  DASH_LOG_TRACE("UnorderedMapLocalRef.at() const", "key:", key);
216  // TODO: Unoptimized, currently calls find(key) twice as operator[](key)
217  // calls insert(key).
218  const_iterator git_value = find(key);
219  if (git_value == end()) {
220  // No equivalent key in map, throw:
221  DASH_THROW(
223  "No element in map for key " << key);
224  }
225  dart_gptr_t gptr_mapped = git_value.dart_gptr();
226  value_type * lptr_value = git_value.local();
227  mapped_type * lptr_mapped = nullptr;
228 
229  _lptr_value_to_mapped(lptr_value, gptr_mapped, lptr_mapped);
230  // Create global reference to mapped value member in element:
231  const_mapped_type_reference mapped(gptr_mapped,
232  lptr_mapped);
233  DASH_LOG_TRACE("UnorderedMapLocalRef.at >", mapped);
234  return mapped;
235  }
236 
237  mapped_type_reference at(const key_type & key)
238  {
239  DASH_LOG_TRACE("UnorderedMapLocalRef.at()", "key:", key);
240  // TODO: Unoptimized, currently calls find(key) twice as operator[](key)
241  // calls insert(key).
242  const_iterator git_value = find(key);
243  if (git_value == end()) {
244  // No equivalent key in map, throw:
245  DASH_THROW(
247  "No element in map for key " << key);
248  }
249  auto mapped = this->operator[](key);
250  DASH_LOG_TRACE("UnorderedMapLocalRef.at >", mapped);
251  return mapped;
252  }
253 
255  // Element Lookup
257 
258  size_type count(const key_type & key) const
259  {
260  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.count()", key);
261  size_type nelem = 0;
262  const_iterator found = find(key);
263  if (found != end()) {
264  nelem = 1;
265  }
266  DASH_LOG_TRACE("UnorderedMapLocalRef.count >", nelem);
267  return nelem;
268  }
269 
270  iterator find(const key_type & key)
271  {
272  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.find()", key);
273  auto & first = begin();
274  auto & last = end();
275  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.find()", first);
276  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.find()", last);
277  auto pred = key_eq();
278  iterator found = std::find_if(
279  first, last,
280  [&](const value_type & v) {
281  DASH_LOG_TRACE("UnorderedMapLocalRef.find.eq",
282  v.first, "==?", key);
283  return pred(v.first, key);
284  });
285  DASH_LOG_TRACE("UnorderedMapLocalRef.find >", found);
286  return found;
287  }
288 
289  const_iterator find(const key_type & key) const
290  {
291  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.find() const", key);
292  auto & first = begin();
293  auto & last = end();
294  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.find()", first);
295  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.find()", last);
296  auto pred = key_eq();
297  const_iterator found = std::find_if(
298  first, last,
299  [&](const value_type & v) {
300  DASH_LOG_TRACE("UnorderedMapLocalRef.find.eq",
301  v.first, "==?", key);
302  return pred(v.first, key);
303  });
304  DASH_LOG_TRACE("UnorderedMapLocalRef.find const >", found);
305  return found;
306  }
307 
309  // Modifiers
311 
312  std::pair<iterator, bool> insert(
314  const value_type & value)
315  {
316  auto && key = value.first;
317  DASH_LOG_DEBUG("UnorderedMapLocalRef.insert()", "key:", key);
318  auto result = std::make_pair(_map->_lend, false);
319 
320  // Look up existing element at given key:
321  DASH_LOG_TRACE("UnorderedMapLocalRef.insert", "element key lookup");
322  const_iterator found = find(key);
323  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.insert", found);
324 
325  if (found != end()) {
326  DASH_LOG_TRACE("UnorderedMapLocalRef.insert", "key found");
327  // Existing element found, no insertion:
328  result.first = iterator(_map, found.pos());
329  result.second = false;
330  } else {
331  DASH_LOG_TRACE("UnorderedMapLocalRef.insert", "key not found");
332  // Unit mapped to the new element's key by the hash function:
333  auto unit = hash_function()(key);
334  // Do not store local unit id in member as _map->_myid is initialized
335  // after this instance (_map->local).
336  auto myid = _map->_myid;
337  DASH_LOG_TRACE("UnorderedMapLocalRef.insert", "target unit:", unit);
338  DASH_LOG_TRACE("UnorderedMapLocalRef.insert", "local unit:", myid);
339  if (unit != myid) {
340  DASH_THROW(
342  "attempted local insert of " <<
343  "key " << key << " which is mapped " <<
344  "to unit " << unit << " by hash function");
345  }
346  auto inserted = _map->_insert_at(unit, value);
347  result.first = inserted.first.local();
348  result.second = inserted.second;
349  // Updated local end iterator of the referenced map:
350  _map->_lend = _map->_lbegin + _map->lsize();
351  DASH_LOG_TRACE("UnorderedMapLocalRef.insert", "updated map.lend:",
352  _map->_lend);
353  }
354  DASH_LOG_DEBUG("UnorderedMapLocalRef.insert >",
355  (result.second ? "inserted" : "existing"), ":",
356  result.first);
357  return result;
358  }
359 
360  template<class InputIterator>
361  void insert(
362  // Iterator at first value in the range to insert.
363  InputIterator first,
364  // Iterator past the last value in the range to insert.
365  InputIterator last)
366  {
367  // TODO: Calling insert() on every single element in the range could cause
368  // multiple calls of globmem.grow(_local_buffer_size).
369  // Could be optimized to allocate additional memory in a single call
370  // of globmem.grow(std::distance(first,last)).
371  for (auto it = first; it != last; ++it) {
372  insert(*it);
373  }
374  }
375 
376  iterator erase(
377  const_iterator it)
378  {
379  DASH_LOG_DEBUG("UnorderedMapLocalRef.erase()", "iterator:", it);
380  erase(*it.first);
381  DASH_LOG_DEBUG("UnorderedMapLocalRef.erase >");
382  }
383 
384  size_type erase(
386  const key_type & key)
387  {
388  DASH_LOG_DEBUG("UnorderedMapLocalRef.erase()", "key:", key);
389  auto b_idx = bucket(key);
390  auto b_size = bucket_size(b_idx);
391  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.erase", b_idx);
392  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.erase", b_size);
393 
394  DASH_THROW(
396  "dash::UnorderedMapLocalRef.erase is not implemented.");
397 
398  DASH_LOG_DEBUG("UnorderedMapLocalRef.erase >");
399  }
400 
401  iterator erase(
403  const_iterator first,
405  const_iterator last)
406  {
407  DASH_LOG_DEBUG("UnorderedMapLocalRef.erase(first,last)");
408  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.erase()", first);
409  DASH_LOG_TRACE_VAR("UnorderedMapLocalRef.erase()", last);
410  for (auto it = first; it != last; ++it) {
411  erase(*it.first);
412  }
413  DASH_LOG_DEBUG("UnorderedMapLocalRef.erase(first,last) >");
414  }
415 
417  // Bucket Interface
419 
420  inline size_type bucket(const key_type & key) const
421  {
422  return _map->bucket(key);
423  }
424 
425  inline size_type bucket_size(size_type bucket_index) const
426  {
427  return _map->bucket_size(bucket_index);
428  }
429 
431  // Observers
433 
434  inline key_equal key_eq() const
435  {
436  return _map->key_eq();
437  }
438 
439  inline hasher hash_function() const
440  {
441  return _map->hash_function();
442  }
443 
444 private:
473  void _lptr_value_to_mapped(
474  // [IN] native pointer to map entry
475  value_type * lptr_value,
476  // [INOUT] corresponding global pointer to mapped value
477  dart_gptr_t & gptr_mapped,
478  // [OUT] corresponding native pointer to mapped value
479  mapped_type * & lptr_mapped) const
480  {
481  // Byte offset of mapped value in element type:
482  auto mapped_offs = offsetof(value_type, second);
483  DASH_LOG_TRACE("UnorderedMap.lptr_value_to_mapped()",
484  "byte offset of mapped member:", mapped_offs);
485  // Increment pointers to element by byte offset of mapped value member:
486  if (lptr_value != nullptr) {
487  if (std::is_standard_layout<value_type>::value) {
488  // Convert to char pointer for byte-wise increment:
489  auto *b_lptr_mapped = reinterpret_cast<char *>(lptr_value);
490  b_lptr_mapped += mapped_offs;
491  // Convert to mapped type pointer:
492  lptr_mapped = reinterpret_cast<mapped_type *>(b_lptr_mapped);
493  } else {
494  lptr_mapped = &(lptr_value->second);
495  }
496  }
497  if (!DART_GPTR_ISNULL(gptr_mapped)) {
498  DASH_ASSERT_RETURNS(
499  dart_gptr_incaddr(&gptr_mapped, mapped_offs),
500  DART_OK);
501  }
502  DASH_LOG_TRACE("UnorderedMap.lptr_value_to_mapped >",
503  "gptr to mapped:", gptr_mapped);
504  DASH_LOG_TRACE("UnorderedMap.lptr_value_to_mapped >",
505  "lptr to mapped:", lptr_mapped);
506  }
507 
508 }; // class UnorderedMapLocalRef
509 
510 #endif // ifdef DOXYGEN
511 
512 } // namespace dash
513 
514 #endif // DASH__MAP__UNORDERED_MAP_LOCAL_REF_H__INCLUDED
Returns second operand.
Definition: Operation.h:218
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
size_t size()
Return the number of units in the global team.
constexpr auto end(RangeType &&range) -> decltype(std::forward< RangeType >(range).end())
Definition: Range.h:98
This class is a simple memory pool which holds allocates elements of size ValueType.
Definition: AllOf.h:8
Signals success.
Definition: dart_types.h:33
constexpr auto begin(RangeType &&range) -> decltype(std::forward< RangeType >(range).begin())
Definition: Range.h:89
GlobIter find_if(GlobIter first, GlobIter last, UnaryPredicate predicate)
Returns an iterator to the first element in the range [first,last) that satisfies the predicate p...
Definition: Find.h:104
Returns second operand.
Definition: Operation.h:201
A Team instance specifies a subset of all available units.
Definition: Team.h:41
Local view specifier of a dynamic map container with support for workload balancing.
DART Global pointer type.
Definition: dart_globmem.h:77
#define DART_GPTR_ISNULL(gptr_)
Test for NULL global pointer.
Definition: dart_globmem.h:118
GlobIter find(GlobIter first, GlobIter last, const ElementType &value)
Returns an iterator to the first element in the range [first,last) that compares equal to val...
Definition: Find.h:22