MADNESS  0.10.1
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 
32 #ifndef MADNESS_WORLD_WORLDHASHMAP_H__INCLUDED
33 #define MADNESS_WORLD_WORLDHASHMAP_H__INCLUDED
34 
35 /// \file worldhashmap.h
36 /// \brief Defines and implements a concurrent hashmap
37 
38 
39 // Why does this exist? It's a bridge from where we are to where we
40 // want to be, which is a mutlthreaded environment probably
41 // based upon the Intel TBB. Don't have the resources right now to
42 // bite off the entire TBB but we probably must in the future.
43 // This is a basic, functional-enough, fast-enough hash map with
44 // vague compatibility with the TBB API.
45 
49 #include <new>
50 #include <stdio.h>
51 #include <map>
52 
53 namespace madness {
54 
55  template <class keyT, class valueT, class hashT> class ConcurrentHashMap;
56 
57  template <class keyT, class valueT, class hashfunT>
58  class ConcurrentHashMap;
59 
60  namespace Hash_private {
61 
62  // A hashtable is an array of nbin bins.
63  // Each bin is a linked list of entries protected by a spinlock.
64  // Each entry holds a key+value pair, a read-write mutex, and a link to the next entry.
65 
66  template <typename keyT, typename valueT>
68  public:
69  typedef std::pair<const keyT, valueT> datumT;
71 
72  class entry<keyT,valueT> * next;
73 
75  : datum(datum), next(next) {}
76  };
77 
78  template <class keyT, class valueT>
79  class bin : private madness::Spinlock {
80  private:
82  typedef std::pair<const keyT, valueT> datumT;
83  // Could pad here to avoid false sharing of cache line but
84  // perhaps better to just use more bins
85  public:
86 
87  entryT* p; // was volatile but all uses are protect by mutex with implied barriers and fences
88  int ninbin; // ditto
89 
90  bin() : p(0),ninbin(0) {}
91 
92  ~bin() {
93  clear();
94  }
95 
96  void clear() {
97  lock(); // BEGIN CRITICAL SECTION
98  while (p) {
99  entryT* n=p->next;
100  delete p;
101  p=n;
102  ninbin--;
103  }
104  MADNESS_ASSERT(ninbin == 0);
105  unlock(); // END CRITICAL SECTION
106  }
107 
108  entryT* find(const keyT& key, const int lockmode) const {
109  bool gotlock;
110  entryT* result;
111  madness::MutexWaiter waiter;
112  do {
113  lock(); // BEGIN CRITICAL SECTION
114  result = match(key);
115  if (result) {
116  gotlock = result->try_lock(lockmode);
117  }
118  else {
119  gotlock = true;
120  }
121  unlock(); // END CRITICAL SECTION
122  if (!gotlock) waiter.wait(); //cpu_relax();
123  }
124  while (!gotlock);
125 
126  return result;
127  }
128 
129  std::pair<entryT*,bool> insert(const datumT& datum, int lockmode) {
130  bool gotlock;
131  entryT* result;
132  bool notfound;
133  madness::MutexWaiter waiter;
134  do {
135  lock(); // BEGIN CRITICAL SECTION
136  result = match(datum.first);
137  notfound = !result;
138  if (notfound) {
139  result = p = new entryT(datum,p);
140  ++ninbin;
141  }
142  gotlock = result->try_lock(lockmode);
143  unlock(); // END CRITICAL SECTION
144  if (!gotlock) waiter.wait(); //cpu_relax();
145  }
146  while (!gotlock);
147 
148  return std::pair<entryT*,bool>(result,notfound);
149  }
150 
151  bool del(const keyT& key, int lockmode) {
152  bool status = false;
153  lock(); // BEGIN CRITICAL SECTION
154  for (entryT *t=p,*prev=0; t; prev=t,t=t->next) {
155  if (t->datum.first == key) {
156  if (prev) {
157  prev->next = t->next;
158  }
159  else {
160  p = t->next;
161  }
162  t->unlock(lockmode);
163  delete t;
164  --ninbin;
165  status = true;
166  break;
167  }
168  }
169  unlock(); // END CRITICAL SECTION
170  return status;
171  }
172 
173  std::size_t size() const {
174  return ninbin;
175  };
176 
177  private:
178  entryT* match(const keyT& key) const {
179  entryT* t;
180  for (t=p; t; t=t->next)
181  if (t->datum.first == key) break;
182  return t;
183  }
184 
185  };
186 
187  /// iterator for hash
188  template <class hashT> class HashIterator {
189  public:
190  typedef typename std::conditional<std::is_const<hashT>::value,
192  typename hashT::entryT>::type entryT;
193  typedef typename std::conditional<std::is_const<hashT>::value,
195  typename hashT::datumT>::type datumT;
196  typedef std::forward_iterator_tag iterator_category;
198  typedef std::ptrdiff_t difference_type;
199  typedef datumT* pointer;
200  typedef datumT& reference;
201 
202  private:
203  hashT* h; // Associated hash table
204  int bin; // Current bin
205  entryT* entry; // Current entry in bin ... zero means at end
206 
207  template <class otherHashT>
208  friend class HashIterator;
209 
210  /// If the entry is null (end of current bin) finds next non-empty bin
212  while (!entry) {
213  ++bin;
214  if ((unsigned) bin == h->nbins) {
215  entry = 0;
216  return;
217  }
218  entry = h->bins[bin].p;
219  }
220  return;
221  }
222 
223  public:
224 
225  /// Makes invalid iterator
226  HashIterator() : h(0), bin(-1), entry(0) {}
227 
228  /// Makes begin/end iterator
229  HashIterator(hashT* h, bool begin)
230  : h(h), bin(-1), entry(0) {
231  if (begin) next_non_null_entry();
232  }
233 
234  /// Makes iterator to specific entry
236  : h(h), bin(bin), entry(entry) {}
237 
238  /// Copy constructor
240  : h(other.h), bin(other.bin), entry(other.entry) {}
241 
242  /// Implicit conversion of another hash type to this hash type
243 
244  /// This allows implicit conversion from hash types to const hash
245  /// types.
246  template <class otherHashT>
248  : h(other.h), bin(other.bin), entry(other.entry) {}
249 
251  if (!entry) return *this;
252  entry = entry->next;
254  return *this;
255  }
256 
258  HashIterator old(*this);
259  operator++();
260  return old;
261  }
262 
263  /// Difference between iterators \em only supported for this=start and other=end
264 
265  /// This exists to support construction of range for parallel iteration
266  /// over the entire container.
267  int distance(const HashIterator& other) const {
268  MADNESS_ASSERT(h == other.h && other == h->end() && *this == h->begin());
269  return h->size();
270  }
271 
272  /// Only positive increments are supported
273 
274  /// This exists to support splitting of range for parallel iteration.
275  void advance(int n) {
276  if (n==0 || !entry) return;
277  MADNESS_ASSERT(n>=0);
278 
279  // Linear increment up to end of this bin
280  while (n-- && (entry=entry->next)) {}
282  if (!entry) return; // end
283 
284  if (n <= 0) return;
285 
286  // If here, will point to first entry in
287  // a bin ... determine which bin contains
288  // our end point.
289  while (unsigned(n) >= h->bins[bin].size()) {
290  n -= h->bins[bin].size();
291  ++bin;
292  if (unsigned(bin) == h->nbins) {
293  entry = 0;
294  return; // end
295  }
296  }
297 
298  entry = h->bins[bin].p;
300 
301  // Linear increment to target
302  while (n--) entry=entry->next;
303 
304  return;
305  }
306 
307 
308  bool operator==(const HashIterator& a) const {
309  return entry==a.entry;
310  }
311 
312  bool operator!=(const HashIterator& a) const {
313  return entry!=a.entry;
314  }
315 
318  //if (!entry) throw "Hash iterator: operator*: at end";
319  return entry->datum;
320  }
321 
322  pointer operator->() const {
324  //if (!entry) throw "Hash iterator: operator->: at end";
325  return &entry->datum;
326  }
327  };
328 
329  template <class hashT, int lockmode>
330  class HashAccessor : private NO_DEFAULTS {
331  template <class a,class b,class c> friend class madness::ConcurrentHashMap;
332  public:
333  typedef typename std::conditional<std::is_const<hashT>::value,
336  typedef typename std::conditional<std::is_const<hashT>::value,
340  typedef datumT* pointer;
341  typedef datumT& reference;
342 
343  private:
345  bool gotlock;
346 
347  /// Used by Hash to set entry (assumed that it has the lock already)
348  void set(entryT* entry) {
349  release();
350  this->entry = entry;
351  gotlock = true;
352  }
353 
354  /// Used by Hash after having already released lock and deleted entry
355  void unset() {
356  gotlock = false;
357  entry = 0;
358  }
359 
362  }
363 
364 
365  public:
366  HashAccessor() : entry(0), gotlock(false) {}
367 
369 
370  datumT& operator*() const {
371  if (!entry) MADNESS_EXCEPTION("Hash accessor: operator*: no value", 0);
372  return entry->datum;
373  }
374 
375  datumT* operator->() const {
376  if (!entry) MADNESS_EXCEPTION("Hash accessor: operator->: no value", 0);
377  return &entry->datum;
378  }
379 
380  void release() {
381  if (gotlock) {
382  entry->unlock(lockmode);
383  entry=0;
384  gotlock = false;
385  }
386  }
387 
389  release();
390  }
391  };
392 
393  } // End of namespace Hash_private
394 
395  template < class keyT, class valueT, class hashfunT = Hash<keyT> >
397  public:
399  typedef std::pair<const keyT,valueT> datumT;
406 
407  friend class Hash_private::HashIterator<hashT>;
408  friend class Hash_private::HashIterator<const hashT>;
409 
410  protected:
411  const size_t nbins; // Number of bins
412  binT* bins; // Array of bins
413 
414  private:
415  hashfunT hashfun;
416 
417  //unsigned int hash(const keyT& key) const {return hashfunT::hash(key)%nbins;}
418 
419  static int nbins_prime(int n) {
420  static const int primes[] = {11, 23, 31, 41, 53, 61, 71, 83, 101,
421  131, 181, 239, 293, 359, 421, 557, 673, 821, 953, 1021, 1231,
422  1531, 1747, 2069, 2543, 3011, 4003, 5011, 6073, 7013, 8053,
423  9029, 9907, 17401, 27479, 37847, 48623, 59377, 70667, 81839,
424  93199, 104759, 224759, 350411, 479951, 611969, 746791, 882391,
425  1299743, 2750171, 4256257, 5800159, 7368811, 8960477, 10570871,
426  12195269, 13834133};
427  static const int nprimes = sizeof(primes)/sizeof(int);
428  // n is a user provided estimate of the no. of elements to be put
429  // in the table. Want to make the number of bins a prime number
430  // larger than this.
431  for (int i=0; i<nprimes; ++i) if (n<=primes[i]) return primes[i];
432  return primes[nprimes-1];
433  }
434 
435  unsigned int hash_to_bin(const keyT& key) const {
436  return hashfun(key)%nbins;
437  }
438 
439  public:
440  ConcurrentHashMap(int n=1021, const hashfunT& hf = hashfunT())
441  : nbins(hashT::nbins_prime(n))
442  , bins(new binT[nbins])
443  , hashfun(hf) {}
444 
446  : nbins(h.nbins)
447  , bins(new binT[nbins])
448  , hashfun(h.hashfun) {
449  *this = h;
450  }
451 
452  virtual ~ConcurrentHashMap() {
453  delete [] bins;
454  }
455 
456  hashT& operator=(const hashT& h) {
457  if (this != &h) {
458  this->clear();
459  hashfun = h.hashfun;
460  for (const_iterator p=h.begin(); p!=h.end(); ++p) {
461  [[maybe_unused]] auto&& [it, inserted] = insert(*p);
462  MADNESS_ASSERT(inserted);
463  }
464  }
465  return *this;
466  }
467 
468  [[nodiscard]] std::pair<iterator,bool> insert(const datumT& datum) {
469  int bin = hash_to_bin(datum.first);
470  std::pair<entryT*,bool> result = bins[bin].insert(datum,entryT::NOLOCK);
471  return std::pair<iterator,bool>(iterator(this,bin,result.first),result.second);
472  }
473 
474  /// Returns true if new pair was inserted; false if key is already in the map and the datum was not inserted
475  [[nodiscard]] bool insert(accessor& result, const datumT& datum) {
476  result.release();
477  int bin = hash_to_bin(datum.first);
478  std::pair<entryT*,bool> r = bins[bin].insert(datum,entryT::WRITELOCK);
479  result.set(r.first);
480  return r.second;
481  }
482 
483  /// Returns true if new pair was inserted; false if key is already in the map and the datum was not inserted
484  [[nodiscard]] bool insert(const_accessor& result, const datumT& datum) {
485  result.release();
486  int bin = hash_to_bin(datum.first);
487  std::pair<entryT*,bool> r = bins[bin].insert(datum,entryT::READLOCK);
488  result.set(r.first);
489  return r.second;
490  }
491 
492  /// Returns true if new pair was inserted; false if key is already in the map
493  [[nodiscard]] inline bool insert(accessor& result, const keyT& key) {
494  return insert(result, datumT(key,valueT()));
495  }
496 
497  /// Returns true if new pair was inserted; false if key is already in the map
498  [[nodiscard]] inline bool insert(const_accessor& result, const keyT& key) {
499  return insert(result, datumT(key,valueT()));
500  }
501 
502  [[nodiscard]] bool try_erase(const keyT& key) {
503  if (bins[hash_to_bin(key)].del(key,entryT::NOLOCK)) return true;
504  else return false;
505  }
506 
507  void erase(const iterator& it) {
508  if (it == end()) MADNESS_EXCEPTION("ConcurrentHashMap: erase(iterator): at end", true);
509  [[maybe_unused]] auto erased = try_erase(it->first);
510  MADNESS_ASSERT(erased);
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) {
520  bins[hash_to_bin(item->first)].del(item->first,entryT::WRITELOCK);
521  item.unset();
522  }
523 
524  [[nodiscard]] 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  [[nodiscard]] 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  [[nodiscard]] 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  [[nodiscard]] 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  [[nodiscard]] 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  [[nodiscard]] valueT& operator[](const keyT& key) {
567  std::pair<iterator,bool> it = insert(datumT(key,valueT()));
568  return it.first->second;
569  }
570 
571  [[nodiscard]] iterator begin() {
572  return iterator(this,true);
573  }
574 
575  [[nodiscard]] const_iterator begin() const {
576  return cbegin();
577  }
578 
579  [[nodiscard]] const_iterator cbegin() const {
580  return const_iterator(this,true);
581  }
582 
583  [[nodiscard]] iterator end() {
584  return iterator(this,false);
585  }
586 
587  [[nodiscard]] const_iterator end() const {
588  return cend();
589  }
590 
591  [[nodiscard]] const_iterator cend() const {
592  return const_iterator(this,false);
593  }
594 
595  hashfunT& get_hash() const { return hashfun; }
596 
597  void print_stats() const {
598  for (unsigned int i=0; i<nbins; ++i) {
599  if (i && (i%10)==0) printf("\n");
600  printf("%8d", int(bins[i].size()));
601  }
602  printf("\n");
603  }
604  };
605 }
606 
607 namespace std {
608 
609  template <typename hashT, typename distT>
610  inline void advance( madness::Hash_private::HashIterator<hashT>& it, const distT& dist ) {
611  //std::cout << " in custom advance \n";
612  it.advance(dist);
613  }
614 
615  template <typename hashT>
617  //std::cout << " in custom distance \n";
618  return it.distance(jt);
619  }
620 }
621 
622 #endif // MADNESS_WORLD_WORLDHASHMAP_H__INCLUDED
Disables default copy constructor and assignment operators.
Definition: nodefaults.h:49
Definition: worldhashmap.h:396
bool find(accessor &result, const keyT &key)
Definition: worldhashmap.h:538
hashfunT hashfun
Definition: worldhashmap.h:415
const size_t nbins
Definition: worldhashmap.h:411
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:493
ConcurrentHashMap(const hashT &h)
Definition: worldhashmap.h:445
Hash_private::HashAccessor< const hashT, entryT::READLOCK > const_accessor
Definition: worldhashmap.h:405
void erase(const_accessor &item)
Definition: worldhashmap.h:518
size_t size() const
Definition: worldhashmap.h:560
ConcurrentHashMap< keyT, valueT, hashfunT > hashT
Definition: worldhashmap.h:398
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:484
const_iterator cbegin() const
Definition: worldhashmap.h:579
Hash_private::HashAccessor< hashT, entryT::WRITELOCK > accessor
Definition: worldhashmap.h:404
bool find(const_accessor &result, const keyT &key) const
Definition: worldhashmap.h:547
hashfunT & get_hash() const
Definition: worldhashmap.h:595
void print_stats() const
Definition: worldhashmap.h:597
const_iterator cend() const
Definition: worldhashmap.h:591
static int nbins_prime(int n)
Definition: worldhashmap.h:419
Hash_private::bin< keyT, valueT > binT
Definition: worldhashmap.h:401
void erase(accessor &item)
Definition: worldhashmap.h:513
Hash_private::HashIterator< const hashT > const_iterator
Definition: worldhashmap.h:403
std::pair< iterator, bool > insert(const datumT &datum)
Definition: worldhashmap.h:468
const_iterator begin() const
Definition: worldhashmap.h:575
Hash_private::entry< keyT, valueT > entryT
Definition: worldhashmap.h:400
const_iterator find(const keyT &key) const
Definition: worldhashmap.h:531
iterator begin()
Definition: worldhashmap.h:571
void erase(const iterator &it)
Definition: worldhashmap.h:507
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:475
const_iterator end() const
Definition: worldhashmap.h:587
binT * bins
Definition: worldhashmap.h:412
ConcurrentHashMap(int n=1021, const hashfunT &hf=hashfunT())
Definition: worldhashmap.h:440
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:498
valueT & operator[](const keyT &key)
Definition: worldhashmap.h:566
bool try_erase(const keyT &key)
Definition: worldhashmap.h:502
iterator end()
Definition: worldhashmap.h:583
unsigned int hash_to_bin(const keyT &key) const
Definition: worldhashmap.h:435
hashT & operator=(const hashT &h)
Definition: worldhashmap.h:456
virtual ~ConcurrentHashMap()
Definition: worldhashmap.h:452
Hash_private::HashIterator< hashT > iterator
Definition: worldhashmap.h:402
iterator find(const keyT &key)
Definition: worldhashmap.h:524
void clear()
Definition: worldhashmap.h:556
std::pair< const keyT, valueT > datumT
Definition: worldhashmap.h:399
Definition: worldhashmap.h:330
std::conditional< std::is_const< hashT >::value, typename std::add_const< typename hashT::datumT >::type, typename hashT::datumT >::type datumT
Definition: worldhashmap.h:338
datumT & reference
Definition: worldhashmap.h:341
void convert_read_lock_to_write_lock()
Definition: worldhashmap.h:360
void release()
Definition: worldhashmap.h:380
void unset()
Used by Hash after having already released lock and deleted entry.
Definition: worldhashmap.h:355
datumT value_type
Definition: worldhashmap.h:339
void set(entryT *entry)
Used by Hash to set entry (assumed that it has the lock already)
Definition: worldhashmap.h:348
~HashAccessor()
Definition: worldhashmap.h:388
datumT & operator*() const
Definition: worldhashmap.h:370
datumT * pointer
Definition: worldhashmap.h:340
datumT * operator->() const
Definition: worldhashmap.h:375
entryT * entry
Definition: worldhashmap.h:344
HashAccessor()
Definition: worldhashmap.h:366
std::conditional< std::is_const< hashT >::value, typename std::add_const< typename hashT::entryT >::type, typename hashT::entryT >::type entryT
Definition: worldhashmap.h:335
HashAccessor(entryT *entry)
Definition: worldhashmap.h:368
bool gotlock
Definition: worldhashmap.h:345
iterator for hash
Definition: worldhashmap.h:188
datumT * pointer
Definition: worldhashmap.h:199
HashIterator & operator++()
Definition: worldhashmap.h:250
pointer operator->() const
Definition: worldhashmap.h:322
std::conditional< std::is_const< hashT >::value, typename std::add_const< typename hashT::datumT >::type, typename hashT::datumT >::type datumT
Definition: worldhashmap.h:195
HashIterator()
Makes invalid iterator.
Definition: worldhashmap.h:226
std::conditional< std::is_const< hashT >::value, typename std::add_const< typename hashT::entryT >::type, typename hashT::entryT >::type entryT
Definition: worldhashmap.h:192
bool operator!=(const HashIterator &a) const
Definition: worldhashmap.h:312
int distance(const HashIterator &other) const
Difference between iterators only supported for this=start and other=end.
Definition: worldhashmap.h:267
int bin
Definition: worldhashmap.h:204
datumT value_type
Definition: worldhashmap.h:197
HashIterator operator++(int)
Definition: worldhashmap.h:257
HashIterator(const HashIterator< otherHashT > &other)
Implicit conversion of another hash type to this hash type.
Definition: worldhashmap.h:247
HashIterator(const HashIterator &other)
Copy constructor.
Definition: worldhashmap.h:239
reference operator*() const
Definition: worldhashmap.h:316
void advance(int n)
Only positive increments are supported.
Definition: worldhashmap.h:275
std::forward_iterator_tag iterator_category
Definition: worldhashmap.h:196
entryT * entry
Definition: worldhashmap.h:205
bool operator==(const HashIterator &a) const
Definition: worldhashmap.h:308
void next_non_null_entry()
If the entry is null (end of current bin) finds next non-empty bin.
Definition: worldhashmap.h:211
HashIterator(hashT *h, int bin, entryT *entry)
Makes iterator to specific entry.
Definition: worldhashmap.h:235
hashT * h
Definition: worldhashmap.h:203
std::ptrdiff_t difference_type
Definition: worldhashmap.h:198
datumT & reference
Definition: worldhashmap.h:200
HashIterator(hashT *h, bool begin)
Makes begin/end iterator.
Definition: worldhashmap.h:229
Definition: worldhashmap.h:79
entryT * p
Definition: worldhashmap.h:87
entryT * find(const keyT &key, const int lockmode) const
Definition: worldhashmap.h:108
void clear()
Definition: worldhashmap.h:96
entryT * match(const keyT &key) const
Definition: worldhashmap.h:178
entry< keyT, valueT > entryT
Definition: worldhashmap.h:81
bool del(const keyT &key, int lockmode)
Definition: worldhashmap.h:151
std::pair< entryT *, bool > insert(const datumT &datum, int lockmode)
Definition: worldhashmap.h:129
std::size_t size() const
Definition: worldhashmap.h:173
int ninbin
Definition: worldhashmap.h:88
std::pair< const keyT, valueT > datumT
Definition: worldhashmap.h:82
~bin()
Definition: worldhashmap.h:92
bin()
Definition: worldhashmap.h:90
Definition: worldhashmap.h:67
datumT datum
Definition: worldhashmap.h:70
std::pair< const keyT, valueT > datumT
Definition: worldhashmap.h:69
class entry< keyT, valueT > * next
Definition: worldhashmap.h:72
entry(const datumT &datum, entry< keyT, valueT > *next)
Definition: worldhashmap.h:74
Definition: worldmutex.h:306
void convert_read_lock_to_write_lock() const
Converts read to write lock without releasing the read lock.
Definition: worldmutex.h:388
static const int WRITELOCK
Definition: worldmutex.h:312
static const int READLOCK
Definition: worldmutex.h:311
bool try_lock(int lockmode) const
Definition: worldmutex.h:330
void unlock(int lockmode) const
Definition: worldmutex.h:379
static const int NOLOCK
Definition: worldmutex.h:310
Definition: worldmutex.h:109
void wait()
Definition: worldmutex.cc:103
Spinlock using pthread spinlock operations.
Definition: worldmutex.h:253
void lock() const
Acquire the spinlock waiting if necessary.
Definition: worldmutex.h:277
void unlock() const
Free a spinlock owned by this thread.
Definition: worldmutex.h:287
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition: derivatives.cc:72
Defines madness::MadnessException for exception handling.
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition: madness_exception.h:119
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition: madness_exception.h:134
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
Function< T, NDIM > sum(World &world, const std::vector< Function< T, NDIM > > &f, bool fence=true)
Returns new function — q = sum_i f[i].
Definition: vmra.h:1421
std::size_t hashT
The hash value type.
Definition: worldhash.h:145
std::string type(const PairType &n)
Definition: PNOParameters.h:18
Definition: mraimpl.h:50
void advance(madness::Hash_private::HashIterator< hashT > &it, const distT &dist)
Definition: worldhashmap.h:610
int distance(const madness::Hash_private::HashIterator< hashT > &it, const madness::Hash_private::HashIterator< hashT > &jt)
Definition: worldhashmap.h:616
static const double a
Definition: nonlinschro.cc:118
std::pair< int, double > valueT
Definition: test_binsorter.cc:6
double dist(const Vector< double, 3 > v1, const Vector< double, 3 > v2)
distance between v1 and v2
Definition: test_localizer.cc:38
double h(const coord_1d &r)
Definition: testgconv.cc:68
const char * status[2]
Definition: testperiodic.cc:43
Defines hash functions for use in distributed containers.
Implements Mutex, MutexFair, Spinlock, ConditionVariable.