atlas  0.6
hashtable_def.h
Go to the documentation of this file.
1 #include <stdexcept>
2 
3 namespace atlas {
4 namespace hashtable {
5 
6 /* template class constants must be defined outside class definition */
7 
8 template <class Entry, typename Number>
9  const Number HashTable<Entry,Number>::empty = ~Number(0);
10 
11 template <class Entry, typename Number>
13 
14 /* the constructor builds |d_hash| to match the contents of |d_pool| */
15 template <class Entry, typename Number>
16  HashTable<Entry,Number>::HashTable(typename Entry::Pooltype& pool)
17  : d_mod(256),d_hash(), d_pool(pool) // caller supplies pool reference
18  {
19  reconstruct();
20  }
21 
22 template <class Entry, typename Number>
24  {
25  // the old value of d_hash is thrown away
26  d_hash=std::vector<Number>(d_mod,empty); // get a fresh hash table
27 
28  // now rehash all old entries
29  for (size_t i=0; i<d_pool.size(); ++i)
30  {
31  size_t h=Entry(d_pool[i]).hashCode(d_mod);
32 
33  while (d_hash[h]!=empty)
34  if (++h==d_mod) h=0; // find empty slot
35  d_hash[h]=Number(i); // fill it
36 
37  }
38  }
39 
40 template <class Entry, typename Number>
42  {
43  while (d_pool.size()>=max_fill())
44  d_mod=d_mod<<1; // keep it a power of 2
45 
46  rehash();
47  }
48 /* the accessor |find| is fairly easy; it need not (and cannot) rehash */
49 
50 template <class Entry, typename Number>
51  Number HashTable<Entry,Number>::find (const Entry& x) const
52  { Number i;
53  size_t h=x.hashCode(d_mod);
54 
55  // the following loop terminates because empty slots are always present
56  while ((i=d_hash[h])!=empty and x!=d_pool[i])
57  if (++h==d_mod) h=0; // move past used slot, wrap around
58 
59  return i; // return either sequence number found, or else empty
60  }
61 
62 /* the manipulator |match| is like |find|, but with extension of the hash
63  table, which in some cases invloves rehahshing, if a new element is
64  encountered
65 */
66 
67 template <class Entry, typename Number>
68  Number HashTable<Entry,Number>::match (const Entry& x)
69  { Number i;
70  size_t h=x.hashCode(d_mod);
71 
72  // the following loop terminates because empty slots are always present
73  while ((i=d_hash[h])!=empty and x!=d_pool[i])
74  if (++h==d_mod) h=0; // move past used slot, wrap around
75 
76  if (i!=empty) return i; // return sequence number if found
77 
78  // now we know x is absent from the table, and h is an empty slot
79 
80  /* Check if d_pool.size() gets too big to represented by a Number. If
81  Number==size_t then this can never happen (we would have exhausted all
82  addressable memory long before) so we shall suppose the contrary, and
83  test whether casting to Number and back to size_t changes its value.
84  */
85 
86  if (size_t(Number(d_pool.size()))!=d_pool.size())
87  throw std::runtime_error("Hash table overflow");
88 
89  // now test if rehash is necessary
90  if (d_pool.size()>=max_fill()) // then we expand d_hash, and rehash
91  {
92  d_mod=d_mod<<1; // keep it a power of 2
93 
94  rehash();
95 
96  // finally recompute hash code of x
97  h=x.hashCode(d_mod);
98 
99  // and locate its slot, knowing that x is absent from d_pool
100  while (d_hash[h]!=empty)
101  if (++h==d_mod) h=0; /* find free slot */
102 
103  } // endif (rehashing necessary)
104 
105  // at this point x is a new entry that will be stored at d_hash[h]
106 
107  d_hash[h]= Number(d_pool.size()); // this is the sequence number of x
108  d_pool.push_back(x); // store x at that position in d_pool
109 
110  return d_hash[h];
111  }
112 
113 } // |namespace hashtable|
114 } // |namespace atlas|
Entry::Pooltype & d_pool
Definition: hashtable.h:70
size_t d_mod
Definition: hashtable.h:68
size_t max_fill() const
Definition: hashtable.h:94
void reconstruct()
Definition: hashtable_def.h:41
Number find(const Entry &) const
Definition: hashtable_def.h:51
Number match(const Entry &)
Definition: hashtable_def.h:68
void rehash()
Definition: hashtable_def.h:23
Definition: Atlas.h:38
static const Number empty
Definition: hashtable.h:76
static const float fill_fraction
Definition: hashtable.h:77
HashTable(typename Entry::Pooltype &pool)
Definition: hashtable_def.h:16
std::vector< Number > d_hash
Definition: hashtable.h:69