33 #ifndef MADNESS_WORLD_WORLDHASHMAP_H__INCLUDED
34 #define MADNESS_WORLD_WORLDHASHMAP_H__INCLUDED
59 template <
class keyT,
class valueT,
class hashfunT>
62 namespace Hash_private {
68 template <
typename keyT,
typename valueT>
71 typedef std::pair<const keyT, valueT>
datumT;
77 : datum(datum), next(next) {}
80 template <
class keyT,
class valueT>
84 typedef std::pair<const keyT, valueT> datumT;
92 bin() : p(0),ninbin(0) {}
106 MADNESS_ASSERT(ninbin == 0);
110 entryT*
find(
const keyT& key,
const int lockmode)
const {
118 gotlock = result->
try_lock(lockmode);
124 if (!gotlock) waiter.
wait();
131 std::pair<entryT*,bool>
insert(
const datumT& datum,
int lockmode) {
138 result = match(datum.first);
141 result = p =
new entryT(datum,p);
144 gotlock = result->
try_lock(lockmode);
146 if (!gotlock) waiter.
wait();
150 return std::pair<entryT*,bool>(result,notfound);
153 bool del(
const keyT& key,
int lockmode) {
156 for (entryT *t=p,*prev=0; t; prev=t,t=t->
next) {
157 if (t->datum.first == key) {
159 prev->next = t->next;
180 entryT* match(
const keyT& key)
const {
182 for (t=p; t; t=t->
next)
183 if (t->datum.first == key)
break;
195 typedef typename madness::if_<std::is_const<hashT>,
209 template <
class otherHashT>
213 void next_non_null_entry() {
216 if ((
unsigned) bin == h->nbins) {
220 entry = h->bins[bin].p;
232 : h(h), bin(-1), entry(0) {
233 if (begin) next_non_null_entry();
238 : h(h), bin(bin), entry(entry) {}
242 : h(other.h), bin(other.bin), entry(other.entry) {}
248 template <
class otherHashT>
250 : h(other.h), bin(other.bin), entry(other.entry) {}
253 if (!entry)
return *
this;
255 next_non_null_entry();
270 MADNESS_ASSERT(h == other.h && other == h->end() && *
this == h->begin());
278 if (n==0 || !entry)
return;
279 MADNESS_ASSERT(n>=0);
282 while (n-- && (entry=entry->next)) {}
283 next_non_null_entry();
291 while (
unsigned(n) >= h->bins[bin].size()) {
292 n -= h->bins[bin].size();
294 if (
unsigned(bin) == h->nbins) {
300 entry = h->bins[bin].p;
301 MADNESS_ASSERT(entry);
304 while (n--) entry=entry->next;
311 return entry==a.entry;
315 return entry!=a.entry;
319 MADNESS_ASSERT(entry);
325 MADNESS_ASSERT(entry);
327 return &entry->datum;
331 template <
class hashT,
int lockmode>
335 typedef typename madness::if_<std::is_const<hashT>,
336 typename std::add_const<typename hashT::entryT>::type,
338 typedef typename madness::if_<std::is_const<hashT>,
339 typename std::add_const<typename hashT::datumT>::type,
350 void set(entryT* entry) {
362 void convert_read_lock_to_write_lock() {
363 if (entry) entry->convert_read_lock_to_write_lock();
379 return &entry->datum;
384 entry->unlock(lockmode);
397 template <
class keyT,
class valueT,
class hashfunT = Hash<keyT> >
398 class ConcurrentHashMap {
401 typedef std::pair<const keyT,valueT>
datumT;
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,
429 static const int nprimes =
sizeof(primes)/
sizeof(
int);
433 for (
int i=0; i<nprimes; ++i)
if (n<=primes[i])
return primes[i];
434 return primes[nprimes-1];
437 unsigned int hash_to_bin(
const keyT& key)
const {
438 return hashfun(key)%
nbins;
443 : nbins(hashT::nbins_prime(n))
444 , bins(new binT[nbins])
449 , bins(new binT[nbins])
450 , hashfun(h.hashfun) {
462 for (const_iterator p=h.
begin(); p!=h.
end(); ++p) {
469 std::pair<iterator,bool>
insert(
const datumT& datum) {
470 int bin = hash_to_bin(datum.first);
472 return std::pair<iterator,bool>(
iterator(
this,bin,result.first),result.second);
476 bool insert(accessor& result,
const datumT& datum) {
478 int bin = hash_to_bin(datum.first);
485 bool insert(const_accessor& result,
const datumT& datum) {
487 int bin = hash_to_bin(datum.first);
494 inline bool insert(accessor& result,
const keyT& key) {
499 inline bool insert(const_accessor& result,
const keyT& key) {
503 std::size_t
erase(
const keyT& key) {
519 item.convert_read_lock_to_write_lock();
524 iterator
find(
const keyT& key) {
525 int bin = hash_to_bin(key);
527 if (!entry)
return end();
528 else return iterator(
this,bin,entry);
531 const_iterator
find(
const keyT& key)
const {
532 int bin = hash_to_bin(key);
534 if (!entry)
return end();
538 bool find(accessor& result,
const keyT& key) {
540 int bin = hash_to_bin(key);
542 bool foundit = entry;
543 if (foundit) result.set(entry);
547 bool find(const_accessor& result,
const keyT& key)
const {
549 int bin = hash_to_bin(key);
551 bool foundit = entry;
552 if (foundit) result.set(entry);
557 for (
unsigned int i=0; i<
nbins; ++i) bins[i].
clear();
562 for (
size_t i=0; i<
nbins; ++i) sum += bins[i].
size();
567 std::pair<iterator,bool> it =
insert(
datumT(key,valueT()));
568 return it.first->second;
583 const_iterator
end()
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()));
601 template <
typename hashT,
typename distT>
607 template <
typename hashT>
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