MADNESS  version 0.9
worldhashmap.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 
31  $Id$
32 */
33 #ifndef MADNESS_WORLD_WORLDHASHMAP_H__INCLUDED
34 #define MADNESS_WORLD_WORLDHASHMAP_H__INCLUDED
35 
38 
39 
40 // Why does this exist? It's a bridge from where we are to where we
41 // want to be, which is a mutlthreaded environment probably
42 // based upon the Intel TBB. Don't have the resources right now to
43 // bite off the entire TBB but we probably must in the future.
44 // This is a basic, functional-enough, fast-enough hash map with
45 // vague compatibility with the TBB API.
46 
48 #include <madness/world/worldexc.h>
51 #include <new>
52 #include <stdio.h>
53 #include <map>
54 
55 namespace madness {
56 
57  template <class keyT, class valueT, class hashT> class ConcurrentHashMap;
58 
59  template <class keyT, class valueT, class hashfunT>
60  class ConcurrentHashMap;
61 
62  namespace Hash_private {
63 
64  // A hashtable is an array of nbin bins.
65  // Each bin is a linked list of entries protected by a spinlock.
66  // Each entry holds a key+value pair, a read-write mutex, and a link to the next entry.
67 
68  template <typename keyT, typename valueT>
70  public:
71  typedef std::pair<const keyT, valueT> datumT;
72  datumT datum;
73 
74  class entry<keyT,valueT> * volatile next;
75 
76  entry(const datumT& datum, entry<keyT,valueT>* next)
77  : datum(datum), next(next) {}
78  };
79 
80  template <class keyT, class valueT>
81  class bin : private madness::Spinlock {
82  private:
83  typedef entry<keyT,valueT> entryT;
84  typedef std::pair<const keyT, valueT> datumT;
85  // Could pad here to avoid false sharing of cache line but
86  // perhaps better to just use more bins
87  public:
88 
89  entryT* volatile p;
90  int volatile ninbin;
91 
92  bin() : p(0),ninbin(0) {}
93 
94  ~bin() {
95  clear();
96  }
97 
98  void clear() {
99  lock(); // BEGIN CRITICAL SECTION
100  while (p) {
101  entryT* n=p->next;
102  delete p;
103  p=n;
104  ninbin--;
105  }
106  MADNESS_ASSERT(ninbin == 0);
107  unlock(); // END CRITICAL SECTION
108  }
109 
110  entryT* find(const keyT& key, const int lockmode) const {
111  bool gotlock;
112  entryT* result;
113  madness::MutexWaiter waiter;
114  do {
115  lock(); // BEGIN CRITICAL SECTION
116  result = match(key);
117  if (result) {
118  gotlock = result->try_lock(lockmode);
119  }
120  else {
121  gotlock = true;
122  }
123  unlock(); // END CRITICAL SECTION
124  if (!gotlock) waiter.wait(); //cpu_relax();
125  }
126  while (!gotlock);
127 
128  return result;
129  }
130 
131  std::pair<entryT*,bool> insert(const datumT& datum, int lockmode) {
132  bool gotlock;
133  entryT* result;
134  bool notfound;
135  madness::MutexWaiter waiter;
136  do {
137  lock(); // BEGIN CRITICAL SECTION
138  result = match(datum.first);
139  notfound = !result;
140  if (notfound) {
141  result = p = new entryT(datum,p);
142  ++ninbin;
143  }
144  gotlock = result->try_lock(lockmode);
145  unlock(); // END CRITICAL SECTION
146  if (!gotlock) waiter.wait(); //cpu_relax();
147  }
148  while (!gotlock);
149 
150  return std::pair<entryT*,bool>(result,notfound);
151  }
152 
153  bool del(const keyT& key, int lockmode) {
154  bool status = false;
155  lock(); // BEGIN CRITICAL SECTION
156  for (entryT *t=p,*prev=0; t; prev=t,t=t->next) {
157  if (t->datum.first == key) {
158  if (prev) {
159  prev->next = t->next;
160  }
161  else {
162  p = t->next;
163  }
164  t->unlock(lockmode);
165  delete t;
166  --ninbin;
167  status = true;
168  break;
169  }
170  }
171  unlock(); // END CRITICAL SECTION
172  return status;
173  }
174 
175  std::size_t size() const {
176  return ninbin;
177  };
178 
179  private:
180  entryT* match(const keyT& key) const {
181  entryT* t;
182  for (t=p; t; t=t->next)
183  if (t->datum.first == key) break;
184  return t;
185  }
186 
187  };
188 
190  template <class hashT> class HashIterator {
191  public:
192  typedef typename madness::if_<std::is_const<hashT>,
194  typename hashT::entryT>::type entryT;
195  typedef typename madness::if_<std::is_const<hashT>,
197  typename hashT::datumT>::type datumT;
198  typedef std::forward_iterator_tag iterator_category;
199  typedef datumT value_type;
200  typedef std::ptrdiff_t difference_type;
201  typedef datumT* pointer;
202  typedef datumT& reference;
203 
204  private:
205  hashT* h; // Associated hash table
206  int bin; // Current bin
207  entryT* entry; // Current entry in bin ... zero means at end
208 
209  template <class otherHashT>
210  friend class HashIterator;
211 
213  void next_non_null_entry() {
214  while (!entry) {
215  ++bin;
216  if ((unsigned) bin == h->nbins) {
217  entry = 0;
218  return;
219  }
220  entry = h->bins[bin].p;
221  }
222  return;
223  }
224 
225  public:
226 
228  HashIterator() : h(0), bin(-1), entry(0) {}
229 
231  HashIterator(hashT* h, bool begin)
232  : h(h), bin(-1), entry(0) {
233  if (begin) next_non_null_entry();
234  }
235 
237  HashIterator(hashT* h, int bin, entryT* entry)
238  : h(h), bin(bin), entry(entry) {}
239 
242  : h(other.h), bin(other.bin), entry(other.entry) {}
243 
245 
248  template <class otherHashT>
250  : h(other.h), bin(other.bin), entry(other.entry) {}
251 
253  if (!entry) return *this;
254  entry = entry->next;
255  next_non_null_entry();
256  return *this;
257  }
258 
260  HashIterator old(*this);
261  operator++();
262  return old;
263  }
264 
266 
269  int distance(const HashIterator& other) const {
270  MADNESS_ASSERT(h == other.h && other == h->end() && *this == h->begin());
271  return h->size();
272  }
273 
275 
277  void advance(int n) {
278  if (n==0 || !entry) return;
279  MADNESS_ASSERT(n>=0);
280 
281  // Linear increment up to end of this bin
282  while (n-- && (entry=entry->next)) {}
283  next_non_null_entry();
284  if (!entry) return; // end
285 
286  if (n <= 0) return;
287 
288  // If here, will point to first entry in
289  // a bin ... determine which bin contains
290  // our end point.
291  while (unsigned(n) >= h->bins[bin].size()) {
292  n -= h->bins[bin].size();
293  ++bin;
294  if (unsigned(bin) == h->nbins) {
295  entry = 0;
296  return; // end
297  }
298  }
299 
300  entry = h->bins[bin].p;
301  MADNESS_ASSERT(entry);
302 
303  // Linear increment to target
304  while (n--) entry=entry->next;
305 
306  return;
307  }
308 
309 
310  bool operator==(const HashIterator& a) const {
311  return entry==a.entry;
312  }
313 
314  bool operator!=(const HashIterator& a) const {
315  return entry!=a.entry;
316  }
317 
318  reference operator*() const {
319  MADNESS_ASSERT(entry);
320  //if (!entry) throw "Hash iterator: operator*: at end";
321  return entry->datum;
322  }
323 
324  pointer operator->() const {
325  MADNESS_ASSERT(entry);
326  //if (!entry) throw "Hash iterator: operator->: at end";
327  return &entry->datum;
328  }
329  };
330 
331  template <class hashT, int lockmode>
332  class HashAccessor : private NO_DEFAULTS {
333  template <class a,class b,class c> friend class madness::ConcurrentHashMap;
334  public:
335  typedef typename madness::if_<std::is_const<hashT>,
336  typename std::add_const<typename hashT::entryT>::type,
337  typename hashT::entryT>::type entryT;
338  typedef typename madness::if_<std::is_const<hashT>,
339  typename std::add_const<typename hashT::datumT>::type,
340  typename hashT::datumT>::type datumT;
341  typedef datumT value_type;
342  typedef datumT* pointer;
343  typedef datumT& reference;
344 
345  private:
346  entryT* entry;
347  bool gotlock;
348 
350  void set(entryT* entry) {
351  release();
352  this->entry = entry;
353  gotlock = true;
354  }
355 
357  void unset() {
358  gotlock = false;
359  entry = 0;
360  }
361 
362  void convert_read_lock_to_write_lock() {
363  if (entry) entry->convert_read_lock_to_write_lock();
364  }
365 
366 
367  public:
368  HashAccessor() : entry(0), gotlock(false) {}
369 
370  HashAccessor(entryT* entry) : entry(entry), gotlock(true) {}
371 
372  datumT& operator*() const {
373  if (!entry) MADNESS_EXCEPTION("Hash accessor: operator*: no value", 0);
374  return entry->datum;
375  }
376 
377  datumT* operator->() const {
378  if (!entry) MADNESS_EXCEPTION("Hash accessor: operator->: no value", 0);
379  return &entry->datum;
380  }
381 
382  void release() {
383  if (gotlock) {
384  entry->unlock(lockmode);
385  entry=0;
386  gotlock = false;
387  }
388  }
389 
391  release();
392  }
393  };
394 
395  } // End of namespace Hash_private
396 
397  template < class keyT, class valueT, class hashfunT = Hash<keyT> >
398  class ConcurrentHashMap {
399  public:
401  typedef std::pair<const keyT,valueT> datumT;
408 
409  friend class Hash_private::HashIterator<hashT>;
410  friend class Hash_private::HashIterator<const hashT>;
411 
412  protected:
413  const size_t nbins; // Number of bins
414  binT* bins; // Array of bins
415 
416  private:
417  hashfunT hashfun;
418 
419  //unsigned int hash(const keyT& key) const {return hashfunT::hash(key)%nbins;}
420 
421  static int nbins_prime(int n) {
422  static const int primes[] = {11, 23, 31, 41, 53, 61, 71, 83, 101,
423  131, 181, 239, 293, 359, 421, 557, 673, 821, 953, 1021, 1231,
424  1531, 1747, 2069, 2543, 3011, 4003, 5011, 6073, 7013, 8053,
425  9029, 9907, 17401, 27479, 37847, 48623, 59377, 70667, 81839,
426  93199, 104759, 224759, 350411, 479951, 611969, 746791, 882391,
427  1299743, 2750171, 4256257, 5800159, 7368811, 8960477, 10570871,
428  12195269, 13834133};
429  static const int nprimes = sizeof(primes)/sizeof(int);
430  // n is a user provided estimate of the no. of elements to be put
431  // in the table. Want to make the number of bins a prime number
432  // larger than this.
433  for (int i=0; i<nprimes; ++i) if (n<=primes[i]) return primes[i];
434  return primes[nprimes-1];
435  }
436 
437  unsigned int hash_to_bin(const keyT& key) const {
438  return hashfun(key)%nbins;
439  }
440 
441  public:
442  ConcurrentHashMap(int n=1021, const hashfunT& hf = hashfunT())
443  : nbins(hashT::nbins_prime(n))
444  , bins(new binT[nbins])
445  , hashfun(hf) {}
446 
447  ConcurrentHashMap(const hashT& h)
448  : nbins(h.nbins)
449  , bins(new binT[nbins])
450  , hashfun(h.hashfun) {
451  *this = h;
452  }
453 
454  virtual ~ConcurrentHashMap() {
455  delete [] bins;
456  }
457 
458  hashT& operator=(const hashT& h) {
459  if (this != &h) {
460  this->clear();
461  hashfun = h.hashfun;
462  for (const_iterator p=h.begin(); p!=h.end(); ++p) {
463  insert(*p);
464  }
465  }
466  return *this;
467  }
468 
469  std::pair<iterator,bool> insert(const datumT& datum) {
470  int bin = hash_to_bin(datum.first);
471  std::pair<entryT*,bool> result = bins[bin].insert(datum,entryT::NOLOCK);
472  return std::pair<iterator,bool>(iterator(this,bin,result.first),result.second);
473  }
474 
476  bool insert(accessor& result, const datumT& datum) {
477  result.release();
478  int bin = hash_to_bin(datum.first);
479  std::pair<entryT*,bool> r = bins[bin].insert(datum,entryT::WRITELOCK);
480  result.set(r.first);
481  return r.second;
482  }
483 
485  bool insert(const_accessor& result, const datumT& datum) {
486  result.release();
487  int bin = hash_to_bin(datum.first);
488  std::pair<entryT*,bool> r = bins[bin].insert(datum,entryT::READLOCK);
489  result.set(r.first);
490  return r.second;
491  }
492 
494  inline bool insert(accessor& result, const keyT& key) {
495  return insert(result, datumT(key,valueT()));
496  }
497 
499  inline bool insert(const_accessor& result, const keyT& key) {
500  return insert(result, datumT(key,valueT()));
501  }
502 
503  std::size_t erase(const keyT& key) {
504  if (bins[hash_to_bin(key)].del(key,entryT::NOLOCK)) return 1;
505  else return 0;
506  }
507 
508  void erase(const iterator& it) {
509  if (it == end()) MADNESS_EXCEPTION("ConcurrentHashMap: erase(iterator): at end", true);
510  erase(it->first);
511  }
512 
513  void erase(accessor& item) {
514  bins[hash_to_bin(item->first)].del(item->first,entryT::WRITELOCK);
515  item.unset();
516  }
517 
518  void erase(const_accessor& item) {
519  item.convert_read_lock_to_write_lock();
520  bins[hash_to_bin(item->first)].del(item->first,entryT::WRITELOCK);
521  item.unset();
522  }
523 
524  iterator find(const keyT& key) {
525  int bin = hash_to_bin(key);
526  entryT* entry = bins[bin].find(key,entryT::NOLOCK);
527  if (!entry) return end();
528  else return iterator(this,bin,entry);
529  }
530 
531  const_iterator find(const keyT& key) const {
532  int bin = hash_to_bin(key);
533  const entryT* entry = bins[bin].find(key,entryT::NOLOCK);
534  if (!entry) return end();
535  else return const_iterator(this,bin,entry);
536  }
537 
538  bool find(accessor& result, const keyT& key) {
539  result.release();
540  int bin = hash_to_bin(key);
541  entryT* entry = bins[bin].find(key,entryT::WRITELOCK);
542  bool foundit = entry;
543  if (foundit) result.set(entry);
544  return foundit;
545  }
546 
547  bool find(const_accessor& result, const keyT& key) const {
548  result.release();
549  int bin = hash_to_bin(key);
550  entryT* entry = bins[bin].find(key,entryT::READLOCK);
551  bool foundit = entry;
552  if (foundit) result.set(entry);
553  return foundit;
554  }
555 
556  void clear() {
557  for (unsigned int i=0; i<nbins; ++i) bins[i].clear();
558  }
559 
560  size_t size() const {
561  size_t sum = 0;
562  for (size_t i=0; i<nbins; ++i) sum += bins[i].size();
563  return sum;
564  }
565 
566  valueT& operator[](const keyT& key) {
567  std::pair<iterator,bool> it = insert(datumT(key,valueT()));
568  return it.first->second;
569  }
570 
571  iterator begin() {
572  return iterator(this,true);
573  }
574 
575  const_iterator begin() const {
576  return const_iterator(this,true);
577  }
578 
579  iterator end() {
580  return iterator(this,false);
581  }
582 
583  const_iterator end() const {
584  return const_iterator(this,false);
585  }
586 
587  hashfunT& get_hash() const { return hashfun; }
588 
589  void print_stats() const {
590  for (unsigned int i=0; i<nbins; ++i) {
591  if (i && (i%10)==0) printf("\n");
592  printf("%8d", int(bins[i].size()));
593  }
594  printf("\n");
595  }
596  };
597 }
598 
599 namespace std {
600 
601  template <typename hashT, typename distT>
602  inline void advance( madness::Hash_private::HashIterator<hashT>& it, const distT& dist ) {
603  //std::cout << " in custom advance \n";
604  it.advance(dist);
605  }
606 
607  template <typename hashT>
609  //std::cout << " in custom distance \n";
610  return it.distance(jt);
611  }
612 }
613 
614 #endif // MADNESS_WORLD_WORLDHASHMAP_H__INCLUDED
int distance(const HashIterator &other) const
Difference between iterators only supported for this=start and other=end.
Definition: worldhashmap.h:269
HashIterator(hashT *h, int bin, entryT *entry)
Makes iterator to specific entry.
Definition: worldhashmap.h:237
void erase(const_accessor &item)
Definition: worldhashmap.h:518
iterator for hash
Definition: worldhashmap.h:190
void clear()
Definition: worldhashmap.h:98
void release()
Definition: worldhashmap.h:382
const_iterator begin() const
Definition: worldhashmap.h:575
Definition: worldhashmap.h:332
ConcurrentHashMap< keyT, valueT, hashfunT > hashT
Definition: worldhashmap.h:400
iterator end()
Definition: worldhashmap.h:579
datumT & operator*() const
Definition: worldhashmap.h:372
static const int READLOCK
Definition: worldmutex.h:250
std::pair< entryT *, bool > insert(const datumT &datum, int lockmode)
Definition: worldhashmap.h:131
void clear()
Definition: worldhashmap.h:556
Defines hash functions for use in distributed containers.
HashIterator operator++(int)
Definition: worldhashmap.h:259
static const int NOLOCK
Definition: worldmutex.h:249
HashAccessor()
Definition: worldhashmap.h:368
virtual ~ConcurrentHashMap()
Definition: worldhashmap.h:454
void unlock() const
Free a spinlock owned by this thread.
Definition: worldmutex.h:230
Hash_private::HashIterator< const hashT > const_iterator
Definition: worldhashmap.h:405
iterator begin()
Definition: worldhashmap.h:571
Definition: mpreal.h:3066
std::pair< const keyT, valueT > datumT
Definition: worldhashmap.h:401
std::forward_iterator_tag iterator_category
Definition: worldhashmap.h:198
const T type
Definition: type_traits_bits.h:228
void lock() const
Acquire the spinlock waiting if necessary.
Definition: worldmutex.h:224
HashIterator(const HashIterator< otherHashT > &other)
Implicit conversion of another hash type to this hash type.
Definition: worldhashmap.h:249
Definition: worldmutex.h:72
Definition: worldhashmap.h:81
bool try_lock(int lockmode) const
Definition: worldmutex.h:269
bool operator!=(const HashIterator &a) const
Definition: worldhashmap.h:314
size_t size() const
Definition: worldhashmap.h:560
void wait()
Definition: worldmutex.cc:43
void print_stats() const
Definition: worldhashmap.h:589
Definition: worldhashmap.h:57
madness::if_< std::is_const< hashT >, typename std::add_const< typename hashT::datumT >::type, typename hashT::datumT >::type datumT
Definition: worldhashmap.h:340
bool insert(const_accessor &result, const datumT &datum)
Returns true if new pair was inserted; false if key is already in the map and the datum was not inser...
Definition: worldhashmap.h:485
std::size_t erase(const keyT &key)
Definition: worldhashmap.h:503
madness::if_< std::is_const< hashT >, typename std::add_const< typename hashT::datumT >::type, typename hashT::datumT >::type datumT
Definition: worldhashmap.h:197
const size_t nbins
Definition: worldhashmap.h:413
Definition: enable_if.h:148
class entry< keyT, valueT > *volatile next
Definition: worldhashmap.h:74
datumT datum
Definition: worldhashmap.h:72
Hash_private::HashAccessor< const hashT, entryT::READLOCK > const_accessor
Definition: worldhashmap.h:407
HashIterator()
Makes invalid iterator.
Definition: worldhashmap.h:228
const_iterator find(const keyT &key) const
Definition: worldhashmap.h:531
datumT * pointer
Definition: worldhashmap.h:201
bool del(const keyT &key, int lockmode)
Definition: worldhashmap.h:153
Hash_private::HashAccessor< hashT, entryT::WRITELOCK > accessor
Definition: worldhashmap.h:406
int volatile ninbin
Definition: worldhashmap.h:90
FLOAT a(int j, FLOAT z)
Definition: y1.cc:86
hashT & operator=(const hashT &h)
Definition: worldhashmap.h:458
valueT & operator[](const keyT &key)
Definition: worldhashmap.h:566
std::pair< iterator, bool > insert(const datumT &datum)
Definition: worldhashmap.h:469
ConcurrentHashMap(const hashT &h)
Definition: worldhashmap.h:447
pointer operator->() const
Definition: worldhashmap.h:324
ConcurrentHashMap(int n=1021, const hashfunT &hf=hashfunT())
Definition: worldhashmap.h:442
Implements Mutex, MutexFair, Spinlock, ConditionVariable.
entry(const datumT &datum, entry< keyT, valueT > *next)
Definition: worldhashmap.h:76
Hash_private::HashIterator< hashT > iterator
Definition: worldhashmap.h:404
bool insert(const_accessor &result, const keyT &key)
Returns true if new pair was inserted; false if key is already in the map.
Definition: worldhashmap.h:499
const_iterator end() const
Definition: worldhashmap.h:583
datumT value_type
Definition: worldhashmap.h:199
binT * bins
Definition: worldhashmap.h:414
std::size_t hashT
The hash value type.
Definition: worldhash.h:148
Hash_private::entry< keyT, valueT > entryT
Definition: worldhashmap.h:402
std::ptrdiff_t difference_type
Definition: worldhashmap.h:200
int distance(const madness::Hash_private::HashIterator< hashT > &it, const madness::Hash_private::HashIterator< hashT > &jt)
Definition: worldhashmap.h:608
bool insert(accessor &result, const keyT &key)
Returns true if new pair was inserted; false if key is already in the map.
Definition: worldhashmap.h:494
Hash_private::bin< keyT, valueT > binT
Definition: worldhashmap.h:403
const mpreal sum(const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode)
Definition: mpreal.cc:241
~bin()
Definition: worldhashmap.h:94
void erase(const iterator &it)
Definition: worldhashmap.h:508
datumT & reference
Definition: worldhashmap.h:202
bool find(const_accessor &result, const keyT &key) const
Definition: worldhashmap.h:547
entryT *volatile p
Definition: worldhashmap.h:89
hashfunT & get_hash() const
Definition: worldhashmap.h:587
std::size_t size() const
Definition: worldhashmap.h:175
Definition: worldhashmap.h:69
datumT value_type
Definition: worldhashmap.h:341
void advance(madness::Hash_private::HashIterator< hashT > &it, const distT &dist)
Definition: worldhashmap.h:602
void erase(accessor &item)
Definition: worldhashmap.h:513
entryT * find(const keyT &key, const int lockmode) const
Definition: worldhashmap.h:110
void advance(int n)
Only positive increments are supported.
Definition: worldhashmap.h:277
madness::if_< std::is_const< hashT >, typename std::add_const< typename hashT::entryT >::type, typename hashT::entryT >::type entryT
Definition: worldhashmap.h:337
datumT * operator->() const
Definition: worldhashmap.h:377
madness::if_< std::is_const< hashT >, typename std::add_const< typename hashT::entryT >::type, typename hashT::entryT >::type entryT
Definition: worldhashmap.h:194
static const int WRITELOCK
Definition: worldmutex.h:251
HashAccessor(entryT *entry)
Definition: worldhashmap.h:370
datumT * pointer
Definition: worldhashmap.h:342
bool operator==(const HashIterator &a) const
Definition: worldhashmap.h:310
Definition: worldmutex.h:245
reference operator*() const
Definition: worldhashmap.h:318
bin()
Definition: worldhashmap.h:92
Implements MadnessException.
HashIterator & operator++()
Definition: worldhashmap.h:252
#define MADNESS_EXCEPTION(msg, value)
Definition: worldexc.h:88
Spinlock using pthread spinlock operations.
Definition: worldmutex.h:200
bool find(accessor &result, const keyT &key)
Definition: worldhashmap.h:538
std::pair< const keyT, valueT > datumT
Definition: worldhashmap.h:71
iterator find(const keyT &key)
Definition: worldhashmap.h:524
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
HashIterator(const HashIterator &other)
Copy constructor.
Definition: worldhashmap.h:241
~HashAccessor()
Definition: worldhashmap.h:390
HashIterator(hashT *h, bool begin)
Makes begin/end iterator.
Definition: worldhashmap.h:231
datumT & reference
Definition: worldhashmap.h:343
Disables default copy constructor and assignment operators.
Definition: nodefaults.h:49
bool insert(accessor &result, const datumT &datum)
Returns true if new pair was inserted; false if key is already in the map and the datum was not inser...
Definition: worldhashmap.h:476