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